├── Recommendations ├── .gitignore ├── appsettings.Development.json ├── appsettings.json ├── Connections │ ├── RedisConnection.cs │ └── RedisManager.cs ├── Program.cs ├── Properties │ └── launchSettings.json ├── Recommendations.csproj ├── Recommendations.sln ├── Events │ ├── SubscriberTest.cs │ └── MetricUpdateSubscriber.cs ├── Startup.cs └── Contracts │ ├── Recommendation.cs │ ├── User.cs │ ├── Metric.cs │ └── Experiment.cs ├── README.md ├── heroku-release.sh └── Dockerfile /Recommendations/.gitignore: -------------------------------------------------------------------------------- 1 | .vs 2 | obj 3 | bin 4 | out -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # abetta-rec 2 | The recommendation microservice, capable of performing tests of stat-significance, etc. 3 | -------------------------------------------------------------------------------- /heroku-release.sh: -------------------------------------------------------------------------------- 1 | docker build -t abetta-rec . 2 | heroku container:push -a abetta-rec web 3 | heroku container:release -a abetta-rec web -------------------------------------------------------------------------------- /Recommendations/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build 2 | WORKDIR /DockerSource 3 | 4 | COPY Recommendations/bin/Release/net5.0/. . 5 | 6 | # For local uncomment this and comment line 8 7 | # ENTRYPOINT ["dotnet", "Recommendations.dll"] 8 | CMD ASPNETCORE_URLS=http://*:$PORT dotnet Recommendations.dll -------------------------------------------------------------------------------- /Recommendations/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Redis": { 3 | "Hostname": "", 4 | "Port": "14826", 5 | "Password": "" 6 | }, 7 | "Logging": { 8 | "LogLevel": { 9 | "Default": "Information", 10 | "Microsoft": "Warning", 11 | "Microsoft.Hosting.Lifetime": "Information" 12 | } 13 | }, 14 | "AllowedHosts": "*" 15 | } 16 | -------------------------------------------------------------------------------- /Recommendations/Connections/RedisConnection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Recommendations.Connections 3 | { 4 | public class RedisConnection 5 | { 6 | public RedisConnection() 7 | { 8 | } 9 | 10 | public string Hostname { get; set; } 11 | 12 | public string Port { get; set; } 13 | 14 | public string Password { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Recommendations/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace Recommendations 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Recommendations/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:11565", 8 | "sslPort": 44304 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "swagger", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "Recommendations": { 21 | "commandName": "Project", 22 | "dotnetRunMessages": "true", 23 | "launchBrowser": true, 24 | "launchUrl": "swagger", 25 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 26 | "environmentVariables": { 27 | "ASPNETCORE_ENVIRONMENT": "Development" 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Recommendations/Recommendations.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Recommendations/Recommendations.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.809.3 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recommendations", "Recommendations.csproj", "{EA3EF5E9-6488-47EF-974E-D3B5918A111E}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {EA3EF5E9-6488-47EF-974E-D3B5918A111E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {EA3EF5E9-6488-47EF-974E-D3B5918A111E}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {EA3EF5E9-6488-47EF-974E-D3B5918A111E}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {EA3EF5E9-6488-47EF-974E-D3B5918A111E}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {162AC3D0-76B8-44E8-A98B-2AB70CA92423} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /Recommendations/Events/SubscriberTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Recommendations.Connections; 3 | using StackExchange.Redis; 4 | 5 | namespace Recommendations.Events 6 | { 7 | public class SubscriberTest 8 | { 9 | public static void TestingConnection(ISubscriber subscriber) 10 | { 11 | var experiment = new Experiment() 12 | { 13 | Id = Guid.NewGuid().ToString(), 14 | Name = "Antonis is great " + new Random().NextDouble(), 15 | }; 16 | experiment.MetricsControl.Add(NewMetric()); 17 | experiment.MetricsTreatment.Add(NewMetric(2)); 18 | 19 | var result = RedisManager.JsonSet(MetricUpdateSubscriber.EXPERIMENT_KEY_PREFIX + experiment.Id, experiment.ToString()); 20 | subscriber.Publish(MetricUpdateSubscriber.METRIC_ADDED, experiment.Id); 21 | } 22 | 23 | public static Metric NewMetric(double baseValue = 10) 24 | { 25 | var metric = new Metric() 26 | { 27 | Name = "Weight", 28 | UnitValue = "Kilos", 29 | LessIsBetter = true 30 | }; 31 | metric.Value.Add(GenerateMetric(baseValue)); 32 | metric.Value.Add(GenerateMetric(baseValue)); 33 | metric.Value.Add(GenerateMetric(baseValue)); 34 | metric.Value.Add(GenerateMetric(baseValue)); 35 | return metric; 36 | } 37 | 38 | public static MetricValue GenerateMetric(double baseValue = 10) 39 | { 40 | return new MetricValue() 41 | { 42 | Value = baseValue + new Random().NextDouble(), 43 | Date = Google.Protobuf.WellKnownTypes.Timestamp.FromDateTime(DateTime.UtcNow) 44 | }; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Recommendations/Connections/RedisManager.cs: -------------------------------------------------------------------------------- 1 | using NReJSON; 2 | using StackExchange.Redis; 3 | using System; 4 | using System.Text.Json; 5 | 6 | namespace Recommendations.Connections 7 | { 8 | public sealed class RedisJsonSerializer : ISerializerProxy 9 | { 10 | public TResult Deserialize(RedisResult serializedValue) => 11 | JsonSerializer.Deserialize(serializedValue.ToString()); 12 | 13 | public string Serialize(TObjectType obj) => 14 | JsonSerializer.Serialize(obj); 15 | } 16 | 17 | public class RedisManager 18 | { 19 | private static ConnectionMultiplexer muxer; 20 | 21 | public static void InitializeManager(RedisConnection connectionConfiguration) 22 | { 23 | if (muxer != null) 24 | { 25 | throw new InvalidOperationException("Connection multiplexer has already been initialized"); 26 | } 27 | 28 | muxer = ConnectionMultiplexer.Connect($"{connectionConfiguration.Hostname}:{connectionConfiguration.Port},password={connectionConfiguration.Password}"); 29 | NReJSONSerializer.SerializerProxy = new RedisJsonSerializer(); 30 | } 31 | 32 | public static IDatabase GetConnection() 33 | { 34 | var connection = muxer.GetDatabase(); 35 | return connection; 36 | } 37 | 38 | public static ISubscriber GetSubscriber() 39 | { 40 | var connection = muxer.GetSubscriber(); 41 | return connection; 42 | } 43 | 44 | public static OperationResult JsonSet(string key, T resource) 45 | { 46 | var connection = muxer.GetDatabase(); 47 | var jsonWrite = connection.JsonSet(key, resource); 48 | return jsonWrite; 49 | } 50 | 51 | public static T JsonGet(string key) 52 | { 53 | var connection = muxer.GetDatabase(); 54 | var resource = connection.JsonGet(key); 55 | return resource; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Recommendations/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text.Json.Serialization; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Builder; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.AspNetCore.HttpsPolicy; 9 | using Microsoft.AspNetCore.Mvc; 10 | using Microsoft.Extensions.Configuration; 11 | using Microsoft.Extensions.DependencyInjection; 12 | using Microsoft.Extensions.Hosting; 13 | using Microsoft.Extensions.Logging; 14 | using Microsoft.OpenApi.Models; 15 | using Recommendations.Connections; 16 | using NReJSON; 17 | using Recommendations.Events; 18 | using StackExchange.Redis; 19 | 20 | namespace Recommendations 21 | { 22 | 23 | public class Startup 24 | { 25 | public Startup(IConfiguration configuration) 26 | { 27 | Configuration = configuration; 28 | } 29 | 30 | public IConfiguration Configuration { get; } 31 | 32 | // This method gets called by the runtime. Use this method to add services to the container. 33 | public void ConfigureServices(IServiceCollection services) 34 | { 35 | RedisConnection redisConfiguration = ReadRedisConfiguration(); 36 | RedisManager.InitializeManager(redisConfiguration); 37 | 38 | MetricUpdateSubscriber.Register(); 39 | 40 | services.AddControllers(); 41 | services.AddSwaggerGen(c => 42 | { 43 | c.SwaggerDoc("v1", new OpenApiInfo { Title = "Recommendations", Version = "v1" }); 44 | }); 45 | } 46 | 47 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 48 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 49 | { 50 | if (env.IsDevelopment()) 51 | { 52 | app.UseDeveloperExceptionPage(); 53 | app.UseSwagger(); 54 | app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Recommendations v1")); 55 | } 56 | 57 | app.UseHttpsRedirection(); 58 | 59 | app.UseRouting(); 60 | 61 | app.UseAuthorization(); 62 | 63 | app.UseEndpoints(endpoints => 64 | { 65 | endpoints.MapControllers(); 66 | }); 67 | } 68 | 69 | private RedisConnection ReadRedisConfiguration() 70 | { 71 | var hostname = Configuration.GetValue(typeof(string), "Redis:Hostname") as string; 72 | var port = Configuration.GetValue(typeof(string), "Redis:Port") as string; 73 | var password = Configuration.GetValue(typeof(string), "Redis:Password") as string; 74 | var redisConfiguration = new RedisConnection() 75 | { 76 | Hostname = hostname, 77 | Port = port, 78 | Password = password 79 | }; 80 | return redisConfiguration; 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Recommendations/Events/MetricUpdateSubscriber.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Threading; 4 | using Accord.Statistics.Testing; 5 | using Google.Protobuf; 6 | using Recommendations.Connections; 7 | using StackExchange.Redis; 8 | 9 | namespace Recommendations.Events 10 | { 11 | public class MetricUpdateSubscriber 12 | { 13 | public static readonly string METRIC_ADDED = "abettame:rec:metric-value-added"; 14 | public static readonly string EXPERIMENT_KEY_PREFIX = "experiments:"; 15 | 16 | public static void Register() 17 | { 18 | var subscriber = RedisManager.GetSubscriber(); 19 | subscriber.Subscribe(METRIC_ADDED, (channel, experimentId) => 20 | { 21 | Console.WriteLine("Got notification for experiment: " + (string)experimentId); 22 | var experimentString = RedisManager.JsonGet(EXPERIMENT_KEY_PREFIX + experimentId); 23 | 24 | var experiment = new JsonParser(JsonParser.Settings.Default).Parse(experimentString); 25 | Console.WriteLine("Retrieved experiment: " + (string)experiment.Name); 26 | 27 | var changeDetected = false; 28 | foreach (var metricControl in experiment.MetricsControl) 29 | { 30 | var metricName = metricControl.Name; 31 | var metricTreatment = experiment.MetricsTreatment.Where(x => x.Name == metricName).FirstOrDefault(); 32 | 33 | if (metricTreatment == null) 34 | { 35 | Console.WriteLine($"Did not find metric {metricName} in both control and treatment"); 36 | } 37 | 38 | var controlValues = metricControl.Value.Select(x => x.Value); 39 | var treatmentValues = metricTreatment.Value.Select(x => x.Value); 40 | 41 | var samples = new double[][] 42 | { 43 | controlValues.ToArray(), 44 | treatmentValues.ToArray() 45 | }; 46 | 47 | var anova = new OneWayAnova(samples); 48 | var fTest = anova.FTest; 49 | 50 | if (fTest.PValue > 0.05) 51 | { 52 | Console.WriteLine($"Metric {metricName} does not have significance"); 53 | 54 | // Non significant difference 55 | continue; 56 | } 57 | 58 | changeDetected = true; 59 | var isMovementPositive = fTest.Hypothesis == TwoSampleHypothesis.FirstValueIsGreaterThanSecond && 60 | metricControl.LessIsBetter; 61 | 62 | experiment.Recommendations.Add(new Recommendation() 63 | { 64 | Id = Guid.NewGuid().ToString(), 65 | AvgControl = controlValues.Average(), 66 | AvgTreatment = treatmentValues.Average(), 67 | MetricControl = experiment.MetricsControl[0], 68 | MetricTreatment = experiment.MetricsTreatment[0], 69 | PValue = fTest.PValue 70 | }); 71 | } 72 | 73 | if (changeDetected) 74 | { 75 | RedisManager.JsonSet(EXPERIMENT_KEY_PREFIX + experiment.Id, experiment.ToString()); 76 | } 77 | }); 78 | 79 | //for (var i = 0; i < 1; i++ ) 80 | //{ 81 | // Thread.Sleep(500); 82 | // Console.WriteLine("Testing connection: " + i.ToString()); 83 | // SubscriberTest.TestingConnection(subscriber); 84 | //} 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Recommendations/Contracts/Recommendation.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Generated by the protocol buffer compiler. DO NOT EDIT! 3 | // source: Recommendation.proto 4 | // 5 | #pragma warning disable 1591, 0612, 3021 6 | #region Designer generated code 7 | 8 | using pb = global::Google.Protobuf; 9 | using pbc = global::Google.Protobuf.Collections; 10 | using pbr = global::Google.Protobuf.Reflection; 11 | using scg = global::System.Collections.Generic; 12 | /// Holder for reflection information generated from Recommendation.proto 13 | public static partial class RecommendationReflection { 14 | 15 | #region Descriptor 16 | /// File descriptor for Recommendation.proto 17 | public static pbr::FileDescriptor Descriptor { 18 | get { return descriptor; } 19 | } 20 | private static pbr::FileDescriptor descriptor; 21 | 22 | static RecommendationReflection() { 23 | byte[] descriptorData = global::System.Convert.FromBase64String( 24 | string.Concat( 25 | "ChRSZWNvbW1lbmRhdGlvbi5wcm90bxoMTWV0cmljLnByb3RvIp0BCg5SZWNv", 26 | "bW1lbmRhdGlvbhIKCgJpZBgBIAEoCRIfCg5tZXRyaWNfY29udHJvbBgCIAEo", 27 | "CzIHLk1ldHJpYxIhChBtZXRyaWNfdHJlYXRtZW50GAMgASgLMgcuTWV0cmlj", 28 | "EhMKC2F2Z19jb250cm9sGAQgASgBEhUKDWF2Z190cmVhdG1lbnQYBSABKAES", 29 | "DwoHcF92YWx1ZRgGIAEoAWIGcHJvdG8z")); 30 | descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, 31 | new pbr::FileDescriptor[] { global::MetricReflection.Descriptor, }, 32 | new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { 33 | new pbr::GeneratedClrTypeInfo(typeof(global::Recommendation), global::Recommendation.Parser, new[]{ "Id", "MetricControl", "MetricTreatment", "AvgControl", "AvgTreatment", "PValue" }, null, null, null, null) 34 | })); 35 | } 36 | #endregion 37 | 38 | } 39 | #region Messages 40 | public sealed partial class Recommendation : pb::IMessage 41 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 42 | , pb::IBufferMessage 43 | #endif 44 | { 45 | private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Recommendation()); 46 | private pb::UnknownFieldSet _unknownFields; 47 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 48 | public static pb::MessageParser Parser { get { return _parser; } } 49 | 50 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 51 | public static pbr::MessageDescriptor Descriptor { 52 | get { return global::RecommendationReflection.Descriptor.MessageTypes[0]; } 53 | } 54 | 55 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 56 | pbr::MessageDescriptor pb::IMessage.Descriptor { 57 | get { return Descriptor; } 58 | } 59 | 60 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 61 | public Recommendation() { 62 | OnConstruction(); 63 | } 64 | 65 | partial void OnConstruction(); 66 | 67 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 68 | public Recommendation(Recommendation other) : this() { 69 | id_ = other.id_; 70 | metricControl_ = other.metricControl_ != null ? other.metricControl_.Clone() : null; 71 | metricTreatment_ = other.metricTreatment_ != null ? other.metricTreatment_.Clone() : null; 72 | avgControl_ = other.avgControl_; 73 | avgTreatment_ = other.avgTreatment_; 74 | pValue_ = other.pValue_; 75 | _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); 76 | } 77 | 78 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 79 | public Recommendation Clone() { 80 | return new Recommendation(this); 81 | } 82 | 83 | /// Field number for the "id" field. 84 | public const int IdFieldNumber = 1; 85 | private string id_ = ""; 86 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 87 | public string Id { 88 | get { return id_; } 89 | set { 90 | id_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); 91 | } 92 | } 93 | 94 | /// Field number for the "metric_control" field. 95 | public const int MetricControlFieldNumber = 2; 96 | private global::Metric metricControl_; 97 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 98 | public global::Metric MetricControl { 99 | get { return metricControl_; } 100 | set { 101 | metricControl_ = value; 102 | } 103 | } 104 | 105 | /// Field number for the "metric_treatment" field. 106 | public const int MetricTreatmentFieldNumber = 3; 107 | private global::Metric metricTreatment_; 108 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 109 | public global::Metric MetricTreatment { 110 | get { return metricTreatment_; } 111 | set { 112 | metricTreatment_ = value; 113 | } 114 | } 115 | 116 | /// Field number for the "avg_control" field. 117 | public const int AvgControlFieldNumber = 4; 118 | private double avgControl_; 119 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 120 | public double AvgControl { 121 | get { return avgControl_; } 122 | set { 123 | avgControl_ = value; 124 | } 125 | } 126 | 127 | /// Field number for the "avg_treatment" field. 128 | public const int AvgTreatmentFieldNumber = 5; 129 | private double avgTreatment_; 130 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 131 | public double AvgTreatment { 132 | get { return avgTreatment_; } 133 | set { 134 | avgTreatment_ = value; 135 | } 136 | } 137 | 138 | /// Field number for the "p_value" field. 139 | public const int PValueFieldNumber = 6; 140 | private double pValue_; 141 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 142 | public double PValue { 143 | get { return pValue_; } 144 | set { 145 | pValue_ = value; 146 | } 147 | } 148 | 149 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 150 | public override bool Equals(object other) { 151 | return Equals(other as Recommendation); 152 | } 153 | 154 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 155 | public bool Equals(Recommendation other) { 156 | if (ReferenceEquals(other, null)) { 157 | return false; 158 | } 159 | if (ReferenceEquals(other, this)) { 160 | return true; 161 | } 162 | if (Id != other.Id) return false; 163 | if (!object.Equals(MetricControl, other.MetricControl)) return false; 164 | if (!object.Equals(MetricTreatment, other.MetricTreatment)) return false; 165 | if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(AvgControl, other.AvgControl)) return false; 166 | if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(AvgTreatment, other.AvgTreatment)) return false; 167 | if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(PValue, other.PValue)) return false; 168 | return Equals(_unknownFields, other._unknownFields); 169 | } 170 | 171 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 172 | public override int GetHashCode() { 173 | int hash = 1; 174 | if (Id.Length != 0) hash ^= Id.GetHashCode(); 175 | if (metricControl_ != null) hash ^= MetricControl.GetHashCode(); 176 | if (metricTreatment_ != null) hash ^= MetricTreatment.GetHashCode(); 177 | if (AvgControl != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(AvgControl); 178 | if (AvgTreatment != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(AvgTreatment); 179 | if (PValue != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(PValue); 180 | if (_unknownFields != null) { 181 | hash ^= _unknownFields.GetHashCode(); 182 | } 183 | return hash; 184 | } 185 | 186 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 187 | public override string ToString() { 188 | return pb::JsonFormatter.ToDiagnosticString(this); 189 | } 190 | 191 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 192 | public void WriteTo(pb::CodedOutputStream output) { 193 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 194 | output.WriteRawMessage(this); 195 | #else 196 | if (Id.Length != 0) { 197 | output.WriteRawTag(10); 198 | output.WriteString(Id); 199 | } 200 | if (metricControl_ != null) { 201 | output.WriteRawTag(18); 202 | output.WriteMessage(MetricControl); 203 | } 204 | if (metricTreatment_ != null) { 205 | output.WriteRawTag(26); 206 | output.WriteMessage(MetricTreatment); 207 | } 208 | if (AvgControl != 0D) { 209 | output.WriteRawTag(33); 210 | output.WriteDouble(AvgControl); 211 | } 212 | if (AvgTreatment != 0D) { 213 | output.WriteRawTag(41); 214 | output.WriteDouble(AvgTreatment); 215 | } 216 | if (PValue != 0D) { 217 | output.WriteRawTag(49); 218 | output.WriteDouble(PValue); 219 | } 220 | if (_unknownFields != null) { 221 | _unknownFields.WriteTo(output); 222 | } 223 | #endif 224 | } 225 | 226 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 227 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 228 | void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { 229 | if (Id.Length != 0) { 230 | output.WriteRawTag(10); 231 | output.WriteString(Id); 232 | } 233 | if (metricControl_ != null) { 234 | output.WriteRawTag(18); 235 | output.WriteMessage(MetricControl); 236 | } 237 | if (metricTreatment_ != null) { 238 | output.WriteRawTag(26); 239 | output.WriteMessage(MetricTreatment); 240 | } 241 | if (AvgControl != 0D) { 242 | output.WriteRawTag(33); 243 | output.WriteDouble(AvgControl); 244 | } 245 | if (AvgTreatment != 0D) { 246 | output.WriteRawTag(41); 247 | output.WriteDouble(AvgTreatment); 248 | } 249 | if (PValue != 0D) { 250 | output.WriteRawTag(49); 251 | output.WriteDouble(PValue); 252 | } 253 | if (_unknownFields != null) { 254 | _unknownFields.WriteTo(ref output); 255 | } 256 | } 257 | #endif 258 | 259 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 260 | public int CalculateSize() { 261 | int size = 0; 262 | if (Id.Length != 0) { 263 | size += 1 + pb::CodedOutputStream.ComputeStringSize(Id); 264 | } 265 | if (metricControl_ != null) { 266 | size += 1 + pb::CodedOutputStream.ComputeMessageSize(MetricControl); 267 | } 268 | if (metricTreatment_ != null) { 269 | size += 1 + pb::CodedOutputStream.ComputeMessageSize(MetricTreatment); 270 | } 271 | if (AvgControl != 0D) { 272 | size += 1 + 8; 273 | } 274 | if (AvgTreatment != 0D) { 275 | size += 1 + 8; 276 | } 277 | if (PValue != 0D) { 278 | size += 1 + 8; 279 | } 280 | if (_unknownFields != null) { 281 | size += _unknownFields.CalculateSize(); 282 | } 283 | return size; 284 | } 285 | 286 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 287 | public void MergeFrom(Recommendation other) { 288 | if (other == null) { 289 | return; 290 | } 291 | if (other.Id.Length != 0) { 292 | Id = other.Id; 293 | } 294 | if (other.metricControl_ != null) { 295 | if (metricControl_ == null) { 296 | MetricControl = new global::Metric(); 297 | } 298 | MetricControl.MergeFrom(other.MetricControl); 299 | } 300 | if (other.metricTreatment_ != null) { 301 | if (metricTreatment_ == null) { 302 | MetricTreatment = new global::Metric(); 303 | } 304 | MetricTreatment.MergeFrom(other.MetricTreatment); 305 | } 306 | if (other.AvgControl != 0D) { 307 | AvgControl = other.AvgControl; 308 | } 309 | if (other.AvgTreatment != 0D) { 310 | AvgTreatment = other.AvgTreatment; 311 | } 312 | if (other.PValue != 0D) { 313 | PValue = other.PValue; 314 | } 315 | _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); 316 | } 317 | 318 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 319 | public void MergeFrom(pb::CodedInputStream input) { 320 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 321 | input.ReadRawMessage(this); 322 | #else 323 | uint tag; 324 | while ((tag = input.ReadTag()) != 0) { 325 | switch(tag) { 326 | default: 327 | _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); 328 | break; 329 | case 10: { 330 | Id = input.ReadString(); 331 | break; 332 | } 333 | case 18: { 334 | if (metricControl_ == null) { 335 | MetricControl = new global::Metric(); 336 | } 337 | input.ReadMessage(MetricControl); 338 | break; 339 | } 340 | case 26: { 341 | if (metricTreatment_ == null) { 342 | MetricTreatment = new global::Metric(); 343 | } 344 | input.ReadMessage(MetricTreatment); 345 | break; 346 | } 347 | case 33: { 348 | AvgControl = input.ReadDouble(); 349 | break; 350 | } 351 | case 41: { 352 | AvgTreatment = input.ReadDouble(); 353 | break; 354 | } 355 | case 49: { 356 | PValue = input.ReadDouble(); 357 | break; 358 | } 359 | } 360 | } 361 | #endif 362 | } 363 | 364 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 365 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 366 | void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { 367 | uint tag; 368 | while ((tag = input.ReadTag()) != 0) { 369 | switch(tag) { 370 | default: 371 | _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); 372 | break; 373 | case 10: { 374 | Id = input.ReadString(); 375 | break; 376 | } 377 | case 18: { 378 | if (metricControl_ == null) { 379 | MetricControl = new global::Metric(); 380 | } 381 | input.ReadMessage(MetricControl); 382 | break; 383 | } 384 | case 26: { 385 | if (metricTreatment_ == null) { 386 | MetricTreatment = new global::Metric(); 387 | } 388 | input.ReadMessage(MetricTreatment); 389 | break; 390 | } 391 | case 33: { 392 | AvgControl = input.ReadDouble(); 393 | break; 394 | } 395 | case 41: { 396 | AvgTreatment = input.ReadDouble(); 397 | break; 398 | } 399 | case 49: { 400 | PValue = input.ReadDouble(); 401 | break; 402 | } 403 | } 404 | } 405 | } 406 | #endif 407 | 408 | } 409 | 410 | #endregion 411 | 412 | 413 | #endregion Designer generated code 414 | -------------------------------------------------------------------------------- /Recommendations/Contracts/User.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Generated by the protocol buffer compiler. DO NOT EDIT! 3 | // source: User.proto 4 | // 5 | #pragma warning disable 1591, 0612, 3021 6 | #region Designer generated code 7 | 8 | using pb = global::Google.Protobuf; 9 | using pbc = global::Google.Protobuf.Collections; 10 | using pbr = global::Google.Protobuf.Reflection; 11 | using scg = global::System.Collections.Generic; 12 | /// Holder for reflection information generated from User.proto 13 | public static partial class UserReflection { 14 | 15 | #region Descriptor 16 | /// File descriptor for User.proto 17 | public static pbr::FileDescriptor Descriptor { 18 | get { return descriptor; } 19 | } 20 | private static pbr::FileDescriptor descriptor; 21 | 22 | static UserReflection() { 23 | byte[] descriptorData = global::System.Convert.FromBase64String( 24 | string.Concat( 25 | "CgpVc2VyLnByb3RvIioKDkV4cGVyaW1lbnRJbmZvEgoKAmlkGAEgASgJEgwK", 26 | "BG5hbWUYAiABKAkiOAoEVXNlchIKCgJpZBgBIAEoCRIkCgtleHBlcmltZW50", 27 | "cxgCIAMoCzIPLkV4cGVyaW1lbnRJbmZvYgZwcm90bzM=")); 28 | descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, 29 | new pbr::FileDescriptor[] { }, 30 | new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { 31 | new pbr::GeneratedClrTypeInfo(typeof(global::ExperimentInfo), global::ExperimentInfo.Parser, new[]{ "Id", "Name" }, null, null, null, null), 32 | new pbr::GeneratedClrTypeInfo(typeof(global::User), global::User.Parser, new[]{ "Id", "Experiments" }, null, null, null, null) 33 | })); 34 | } 35 | #endregion 36 | 37 | } 38 | #region Messages 39 | public sealed partial class ExperimentInfo : pb::IMessage 40 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 41 | , pb::IBufferMessage 42 | #endif 43 | { 44 | private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ExperimentInfo()); 45 | private pb::UnknownFieldSet _unknownFields; 46 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 47 | public static pb::MessageParser Parser { get { return _parser; } } 48 | 49 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 50 | public static pbr::MessageDescriptor Descriptor { 51 | get { return global::UserReflection.Descriptor.MessageTypes[0]; } 52 | } 53 | 54 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 55 | pbr::MessageDescriptor pb::IMessage.Descriptor { 56 | get { return Descriptor; } 57 | } 58 | 59 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 60 | public ExperimentInfo() { 61 | OnConstruction(); 62 | } 63 | 64 | partial void OnConstruction(); 65 | 66 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 67 | public ExperimentInfo(ExperimentInfo other) : this() { 68 | id_ = other.id_; 69 | name_ = other.name_; 70 | _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); 71 | } 72 | 73 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 74 | public ExperimentInfo Clone() { 75 | return new ExperimentInfo(this); 76 | } 77 | 78 | /// Field number for the "id" field. 79 | public const int IdFieldNumber = 1; 80 | private string id_ = ""; 81 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 82 | public string Id { 83 | get { return id_; } 84 | set { 85 | id_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); 86 | } 87 | } 88 | 89 | /// Field number for the "name" field. 90 | public const int NameFieldNumber = 2; 91 | private string name_ = ""; 92 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 93 | public string Name { 94 | get { return name_; } 95 | set { 96 | name_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); 97 | } 98 | } 99 | 100 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 101 | public override bool Equals(object other) { 102 | return Equals(other as ExperimentInfo); 103 | } 104 | 105 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 106 | public bool Equals(ExperimentInfo other) { 107 | if (ReferenceEquals(other, null)) { 108 | return false; 109 | } 110 | if (ReferenceEquals(other, this)) { 111 | return true; 112 | } 113 | if (Id != other.Id) return false; 114 | if (Name != other.Name) return false; 115 | return Equals(_unknownFields, other._unknownFields); 116 | } 117 | 118 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 119 | public override int GetHashCode() { 120 | int hash = 1; 121 | if (Id.Length != 0) hash ^= Id.GetHashCode(); 122 | if (Name.Length != 0) hash ^= Name.GetHashCode(); 123 | if (_unknownFields != null) { 124 | hash ^= _unknownFields.GetHashCode(); 125 | } 126 | return hash; 127 | } 128 | 129 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 130 | public override string ToString() { 131 | return pb::JsonFormatter.ToDiagnosticString(this); 132 | } 133 | 134 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 135 | public void WriteTo(pb::CodedOutputStream output) { 136 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 137 | output.WriteRawMessage(this); 138 | #else 139 | if (Id.Length != 0) { 140 | output.WriteRawTag(10); 141 | output.WriteString(Id); 142 | } 143 | if (Name.Length != 0) { 144 | output.WriteRawTag(18); 145 | output.WriteString(Name); 146 | } 147 | if (_unknownFields != null) { 148 | _unknownFields.WriteTo(output); 149 | } 150 | #endif 151 | } 152 | 153 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 154 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 155 | void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { 156 | if (Id.Length != 0) { 157 | output.WriteRawTag(10); 158 | output.WriteString(Id); 159 | } 160 | if (Name.Length != 0) { 161 | output.WriteRawTag(18); 162 | output.WriteString(Name); 163 | } 164 | if (_unknownFields != null) { 165 | _unknownFields.WriteTo(ref output); 166 | } 167 | } 168 | #endif 169 | 170 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 171 | public int CalculateSize() { 172 | int size = 0; 173 | if (Id.Length != 0) { 174 | size += 1 + pb::CodedOutputStream.ComputeStringSize(Id); 175 | } 176 | if (Name.Length != 0) { 177 | size += 1 + pb::CodedOutputStream.ComputeStringSize(Name); 178 | } 179 | if (_unknownFields != null) { 180 | size += _unknownFields.CalculateSize(); 181 | } 182 | return size; 183 | } 184 | 185 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 186 | public void MergeFrom(ExperimentInfo other) { 187 | if (other == null) { 188 | return; 189 | } 190 | if (other.Id.Length != 0) { 191 | Id = other.Id; 192 | } 193 | if (other.Name.Length != 0) { 194 | Name = other.Name; 195 | } 196 | _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); 197 | } 198 | 199 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 200 | public void MergeFrom(pb::CodedInputStream input) { 201 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 202 | input.ReadRawMessage(this); 203 | #else 204 | uint tag; 205 | while ((tag = input.ReadTag()) != 0) { 206 | switch(tag) { 207 | default: 208 | _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); 209 | break; 210 | case 10: { 211 | Id = input.ReadString(); 212 | break; 213 | } 214 | case 18: { 215 | Name = input.ReadString(); 216 | break; 217 | } 218 | } 219 | } 220 | #endif 221 | } 222 | 223 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 224 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 225 | void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { 226 | uint tag; 227 | while ((tag = input.ReadTag()) != 0) { 228 | switch(tag) { 229 | default: 230 | _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); 231 | break; 232 | case 10: { 233 | Id = input.ReadString(); 234 | break; 235 | } 236 | case 18: { 237 | Name = input.ReadString(); 238 | break; 239 | } 240 | } 241 | } 242 | } 243 | #endif 244 | 245 | } 246 | 247 | public sealed partial class User : pb::IMessage 248 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 249 | , pb::IBufferMessage 250 | #endif 251 | { 252 | private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new User()); 253 | private pb::UnknownFieldSet _unknownFields; 254 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 255 | public static pb::MessageParser Parser { get { return _parser; } } 256 | 257 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 258 | public static pbr::MessageDescriptor Descriptor { 259 | get { return global::UserReflection.Descriptor.MessageTypes[1]; } 260 | } 261 | 262 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 263 | pbr::MessageDescriptor pb::IMessage.Descriptor { 264 | get { return Descriptor; } 265 | } 266 | 267 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 268 | public User() { 269 | OnConstruction(); 270 | } 271 | 272 | partial void OnConstruction(); 273 | 274 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 275 | public User(User other) : this() { 276 | id_ = other.id_; 277 | experiments_ = other.experiments_.Clone(); 278 | _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); 279 | } 280 | 281 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 282 | public User Clone() { 283 | return new User(this); 284 | } 285 | 286 | /// Field number for the "id" field. 287 | public const int IdFieldNumber = 1; 288 | private string id_ = ""; 289 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 290 | public string Id { 291 | get { return id_; } 292 | set { 293 | id_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); 294 | } 295 | } 296 | 297 | /// Field number for the "experiments" field. 298 | public const int ExperimentsFieldNumber = 2; 299 | private static readonly pb::FieldCodec _repeated_experiments_codec 300 | = pb::FieldCodec.ForMessage(18, global::ExperimentInfo.Parser); 301 | private readonly pbc::RepeatedField experiments_ = new pbc::RepeatedField(); 302 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 303 | public pbc::RepeatedField Experiments { 304 | get { return experiments_; } 305 | } 306 | 307 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 308 | public override bool Equals(object other) { 309 | return Equals(other as User); 310 | } 311 | 312 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 313 | public bool Equals(User other) { 314 | if (ReferenceEquals(other, null)) { 315 | return false; 316 | } 317 | if (ReferenceEquals(other, this)) { 318 | return true; 319 | } 320 | if (Id != other.Id) return false; 321 | if(!experiments_.Equals(other.experiments_)) return false; 322 | return Equals(_unknownFields, other._unknownFields); 323 | } 324 | 325 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 326 | public override int GetHashCode() { 327 | int hash = 1; 328 | if (Id.Length != 0) hash ^= Id.GetHashCode(); 329 | hash ^= experiments_.GetHashCode(); 330 | if (_unknownFields != null) { 331 | hash ^= _unknownFields.GetHashCode(); 332 | } 333 | return hash; 334 | } 335 | 336 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 337 | public override string ToString() { 338 | return pb::JsonFormatter.ToDiagnosticString(this); 339 | } 340 | 341 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 342 | public void WriteTo(pb::CodedOutputStream output) { 343 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 344 | output.WriteRawMessage(this); 345 | #else 346 | if (Id.Length != 0) { 347 | output.WriteRawTag(10); 348 | output.WriteString(Id); 349 | } 350 | experiments_.WriteTo(output, _repeated_experiments_codec); 351 | if (_unknownFields != null) { 352 | _unknownFields.WriteTo(output); 353 | } 354 | #endif 355 | } 356 | 357 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 358 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 359 | void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { 360 | if (Id.Length != 0) { 361 | output.WriteRawTag(10); 362 | output.WriteString(Id); 363 | } 364 | experiments_.WriteTo(ref output, _repeated_experiments_codec); 365 | if (_unknownFields != null) { 366 | _unknownFields.WriteTo(ref output); 367 | } 368 | } 369 | #endif 370 | 371 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 372 | public int CalculateSize() { 373 | int size = 0; 374 | if (Id.Length != 0) { 375 | size += 1 + pb::CodedOutputStream.ComputeStringSize(Id); 376 | } 377 | size += experiments_.CalculateSize(_repeated_experiments_codec); 378 | if (_unknownFields != null) { 379 | size += _unknownFields.CalculateSize(); 380 | } 381 | return size; 382 | } 383 | 384 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 385 | public void MergeFrom(User other) { 386 | if (other == null) { 387 | return; 388 | } 389 | if (other.Id.Length != 0) { 390 | Id = other.Id; 391 | } 392 | experiments_.Add(other.experiments_); 393 | _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); 394 | } 395 | 396 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 397 | public void MergeFrom(pb::CodedInputStream input) { 398 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 399 | input.ReadRawMessage(this); 400 | #else 401 | uint tag; 402 | while ((tag = input.ReadTag()) != 0) { 403 | switch(tag) { 404 | default: 405 | _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); 406 | break; 407 | case 10: { 408 | Id = input.ReadString(); 409 | break; 410 | } 411 | case 18: { 412 | experiments_.AddEntriesFrom(input, _repeated_experiments_codec); 413 | break; 414 | } 415 | } 416 | } 417 | #endif 418 | } 419 | 420 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 421 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 422 | void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { 423 | uint tag; 424 | while ((tag = input.ReadTag()) != 0) { 425 | switch(tag) { 426 | default: 427 | _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); 428 | break; 429 | case 10: { 430 | Id = input.ReadString(); 431 | break; 432 | } 433 | case 18: { 434 | experiments_.AddEntriesFrom(ref input, _repeated_experiments_codec); 435 | break; 436 | } 437 | } 438 | } 439 | } 440 | #endif 441 | 442 | } 443 | 444 | #endregion 445 | 446 | 447 | #endregion Designer generated code 448 | -------------------------------------------------------------------------------- /Recommendations/Contracts/Metric.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Generated by the protocol buffer compiler. DO NOT EDIT! 3 | // source: Metric.proto 4 | // 5 | #pragma warning disable 1591, 0612, 3021 6 | #region Designer generated code 7 | 8 | using pb = global::Google.Protobuf; 9 | using pbc = global::Google.Protobuf.Collections; 10 | using pbr = global::Google.Protobuf.Reflection; 11 | using scg = global::System.Collections.Generic; 12 | /// Holder for reflection information generated from Metric.proto 13 | public static partial class MetricReflection { 14 | 15 | #region Descriptor 16 | /// File descriptor for Metric.proto 17 | public static pbr::FileDescriptor Descriptor { 18 | get { return descriptor; } 19 | } 20 | private static pbr::FileDescriptor descriptor; 21 | 22 | static MetricReflection() { 23 | byte[] descriptorData = global::System.Convert.FromBase64String( 24 | string.Concat( 25 | "CgxNZXRyaWMucHJvdG8aH2dvb2dsZS9wcm90b2J1Zi90aW1lc3RhbXAucHJv", 26 | "dG8iRgoLTWV0cmljVmFsdWUSKAoEZGF0ZRgBIAEoCzIaLmdvb2dsZS5wcm90", 27 | "b2J1Zi5UaW1lc3RhbXASDQoFdmFsdWUYAiABKAEiXwoGTWV0cmljEgwKBG5h", 28 | "bWUYASABKAkSEgoKdW5pdF92YWx1ZRgCIAEoCRIbCgV2YWx1ZRgDIAMoCzIM", 29 | "Lk1ldHJpY1ZhbHVlEhYKDmxlc3NfaXNfYmV0dGVyGAQgASgIYgZwcm90bzM=")); 30 | descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, 31 | new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.TimestampReflection.Descriptor, }, 32 | new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { 33 | new pbr::GeneratedClrTypeInfo(typeof(global::MetricValue), global::MetricValue.Parser, new[]{ "Date", "Value" }, null, null, null, null), 34 | new pbr::GeneratedClrTypeInfo(typeof(global::Metric), global::Metric.Parser, new[]{ "Name", "UnitValue", "Value", "LessIsBetter" }, null, null, null, null) 35 | })); 36 | } 37 | #endregion 38 | 39 | } 40 | #region Messages 41 | public sealed partial class MetricValue : pb::IMessage 42 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 43 | , pb::IBufferMessage 44 | #endif 45 | { 46 | private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new MetricValue()); 47 | private pb::UnknownFieldSet _unknownFields; 48 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 49 | public static pb::MessageParser Parser { get { return _parser; } } 50 | 51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 52 | public static pbr::MessageDescriptor Descriptor { 53 | get { return global::MetricReflection.Descriptor.MessageTypes[0]; } 54 | } 55 | 56 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 57 | pbr::MessageDescriptor pb::IMessage.Descriptor { 58 | get { return Descriptor; } 59 | } 60 | 61 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 62 | public MetricValue() { 63 | OnConstruction(); 64 | } 65 | 66 | partial void OnConstruction(); 67 | 68 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 69 | public MetricValue(MetricValue other) : this() { 70 | date_ = other.date_ != null ? other.date_.Clone() : null; 71 | value_ = other.value_; 72 | _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); 73 | } 74 | 75 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 76 | public MetricValue Clone() { 77 | return new MetricValue(this); 78 | } 79 | 80 | /// Field number for the "date" field. 81 | public const int DateFieldNumber = 1; 82 | private global::Google.Protobuf.WellKnownTypes.Timestamp date_; 83 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 84 | public global::Google.Protobuf.WellKnownTypes.Timestamp Date { 85 | get { return date_; } 86 | set { 87 | date_ = value; 88 | } 89 | } 90 | 91 | /// Field number for the "value" field. 92 | public const int ValueFieldNumber = 2; 93 | private double value_; 94 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 95 | public double Value { 96 | get { return value_; } 97 | set { 98 | value_ = value; 99 | } 100 | } 101 | 102 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 103 | public override bool Equals(object other) { 104 | return Equals(other as MetricValue); 105 | } 106 | 107 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 108 | public bool Equals(MetricValue other) { 109 | if (ReferenceEquals(other, null)) { 110 | return false; 111 | } 112 | if (ReferenceEquals(other, this)) { 113 | return true; 114 | } 115 | if (!object.Equals(Date, other.Date)) return false; 116 | if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(Value, other.Value)) return false; 117 | return Equals(_unknownFields, other._unknownFields); 118 | } 119 | 120 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 121 | public override int GetHashCode() { 122 | int hash = 1; 123 | if (date_ != null) hash ^= Date.GetHashCode(); 124 | if (Value != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(Value); 125 | if (_unknownFields != null) { 126 | hash ^= _unknownFields.GetHashCode(); 127 | } 128 | return hash; 129 | } 130 | 131 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 132 | public override string ToString() { 133 | return pb::JsonFormatter.ToDiagnosticString(this); 134 | } 135 | 136 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 137 | public void WriteTo(pb::CodedOutputStream output) { 138 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 139 | output.WriteRawMessage(this); 140 | #else 141 | if (date_ != null) { 142 | output.WriteRawTag(10); 143 | output.WriteMessage(Date); 144 | } 145 | if (Value != 0D) { 146 | output.WriteRawTag(17); 147 | output.WriteDouble(Value); 148 | } 149 | if (_unknownFields != null) { 150 | _unknownFields.WriteTo(output); 151 | } 152 | #endif 153 | } 154 | 155 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 156 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 157 | void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { 158 | if (date_ != null) { 159 | output.WriteRawTag(10); 160 | output.WriteMessage(Date); 161 | } 162 | if (Value != 0D) { 163 | output.WriteRawTag(17); 164 | output.WriteDouble(Value); 165 | } 166 | if (_unknownFields != null) { 167 | _unknownFields.WriteTo(ref output); 168 | } 169 | } 170 | #endif 171 | 172 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 173 | public int CalculateSize() { 174 | int size = 0; 175 | if (date_ != null) { 176 | size += 1 + pb::CodedOutputStream.ComputeMessageSize(Date); 177 | } 178 | if (Value != 0D) { 179 | size += 1 + 8; 180 | } 181 | if (_unknownFields != null) { 182 | size += _unknownFields.CalculateSize(); 183 | } 184 | return size; 185 | } 186 | 187 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 188 | public void MergeFrom(MetricValue other) { 189 | if (other == null) { 190 | return; 191 | } 192 | if (other.date_ != null) { 193 | if (date_ == null) { 194 | Date = new global::Google.Protobuf.WellKnownTypes.Timestamp(); 195 | } 196 | Date.MergeFrom(other.Date); 197 | } 198 | if (other.Value != 0D) { 199 | Value = other.Value; 200 | } 201 | _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); 202 | } 203 | 204 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 205 | public void MergeFrom(pb::CodedInputStream input) { 206 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 207 | input.ReadRawMessage(this); 208 | #else 209 | uint tag; 210 | while ((tag = input.ReadTag()) != 0) { 211 | switch(tag) { 212 | default: 213 | _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); 214 | break; 215 | case 10: { 216 | if (date_ == null) { 217 | Date = new global::Google.Protobuf.WellKnownTypes.Timestamp(); 218 | } 219 | input.ReadMessage(Date); 220 | break; 221 | } 222 | case 17: { 223 | Value = input.ReadDouble(); 224 | break; 225 | } 226 | } 227 | } 228 | #endif 229 | } 230 | 231 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 232 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 233 | void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { 234 | uint tag; 235 | while ((tag = input.ReadTag()) != 0) { 236 | switch(tag) { 237 | default: 238 | _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); 239 | break; 240 | case 10: { 241 | if (date_ == null) { 242 | Date = new global::Google.Protobuf.WellKnownTypes.Timestamp(); 243 | } 244 | input.ReadMessage(Date); 245 | break; 246 | } 247 | case 17: { 248 | Value = input.ReadDouble(); 249 | break; 250 | } 251 | } 252 | } 253 | } 254 | #endif 255 | 256 | } 257 | 258 | public sealed partial class Metric : pb::IMessage 259 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 260 | , pb::IBufferMessage 261 | #endif 262 | { 263 | private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Metric()); 264 | private pb::UnknownFieldSet _unknownFields; 265 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 266 | public static pb::MessageParser Parser { get { return _parser; } } 267 | 268 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 269 | public static pbr::MessageDescriptor Descriptor { 270 | get { return global::MetricReflection.Descriptor.MessageTypes[1]; } 271 | } 272 | 273 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 274 | pbr::MessageDescriptor pb::IMessage.Descriptor { 275 | get { return Descriptor; } 276 | } 277 | 278 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 279 | public Metric() { 280 | OnConstruction(); 281 | } 282 | 283 | partial void OnConstruction(); 284 | 285 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 286 | public Metric(Metric other) : this() { 287 | name_ = other.name_; 288 | unitValue_ = other.unitValue_; 289 | value_ = other.value_.Clone(); 290 | lessIsBetter_ = other.lessIsBetter_; 291 | _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); 292 | } 293 | 294 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 295 | public Metric Clone() { 296 | return new Metric(this); 297 | } 298 | 299 | /// Field number for the "name" field. 300 | public const int NameFieldNumber = 1; 301 | private string name_ = ""; 302 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 303 | public string Name { 304 | get { return name_; } 305 | set { 306 | name_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); 307 | } 308 | } 309 | 310 | /// Field number for the "unit_value" field. 311 | public const int UnitValueFieldNumber = 2; 312 | private string unitValue_ = ""; 313 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 314 | public string UnitValue { 315 | get { return unitValue_; } 316 | set { 317 | unitValue_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); 318 | } 319 | } 320 | 321 | /// Field number for the "value" field. 322 | public const int ValueFieldNumber = 3; 323 | private static readonly pb::FieldCodec _repeated_value_codec 324 | = pb::FieldCodec.ForMessage(26, global::MetricValue.Parser); 325 | private readonly pbc::RepeatedField value_ = new pbc::RepeatedField(); 326 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 327 | public pbc::RepeatedField Value { 328 | get { return value_; } 329 | } 330 | 331 | /// Field number for the "less_is_better" field. 332 | public const int LessIsBetterFieldNumber = 4; 333 | private bool lessIsBetter_; 334 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 335 | public bool LessIsBetter { 336 | get { return lessIsBetter_; } 337 | set { 338 | lessIsBetter_ = value; 339 | } 340 | } 341 | 342 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 343 | public override bool Equals(object other) { 344 | return Equals(other as Metric); 345 | } 346 | 347 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 348 | public bool Equals(Metric other) { 349 | if (ReferenceEquals(other, null)) { 350 | return false; 351 | } 352 | if (ReferenceEquals(other, this)) { 353 | return true; 354 | } 355 | if (Name != other.Name) return false; 356 | if (UnitValue != other.UnitValue) return false; 357 | if(!value_.Equals(other.value_)) return false; 358 | if (LessIsBetter != other.LessIsBetter) return false; 359 | return Equals(_unknownFields, other._unknownFields); 360 | } 361 | 362 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 363 | public override int GetHashCode() { 364 | int hash = 1; 365 | if (Name.Length != 0) hash ^= Name.GetHashCode(); 366 | if (UnitValue.Length != 0) hash ^= UnitValue.GetHashCode(); 367 | hash ^= value_.GetHashCode(); 368 | if (LessIsBetter != false) hash ^= LessIsBetter.GetHashCode(); 369 | if (_unknownFields != null) { 370 | hash ^= _unknownFields.GetHashCode(); 371 | } 372 | return hash; 373 | } 374 | 375 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 376 | public override string ToString() { 377 | return pb::JsonFormatter.ToDiagnosticString(this); 378 | } 379 | 380 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 381 | public void WriteTo(pb::CodedOutputStream output) { 382 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 383 | output.WriteRawMessage(this); 384 | #else 385 | if (Name.Length != 0) { 386 | output.WriteRawTag(10); 387 | output.WriteString(Name); 388 | } 389 | if (UnitValue.Length != 0) { 390 | output.WriteRawTag(18); 391 | output.WriteString(UnitValue); 392 | } 393 | value_.WriteTo(output, _repeated_value_codec); 394 | if (LessIsBetter != false) { 395 | output.WriteRawTag(32); 396 | output.WriteBool(LessIsBetter); 397 | } 398 | if (_unknownFields != null) { 399 | _unknownFields.WriteTo(output); 400 | } 401 | #endif 402 | } 403 | 404 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 405 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 406 | void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { 407 | if (Name.Length != 0) { 408 | output.WriteRawTag(10); 409 | output.WriteString(Name); 410 | } 411 | if (UnitValue.Length != 0) { 412 | output.WriteRawTag(18); 413 | output.WriteString(UnitValue); 414 | } 415 | value_.WriteTo(ref output, _repeated_value_codec); 416 | if (LessIsBetter != false) { 417 | output.WriteRawTag(32); 418 | output.WriteBool(LessIsBetter); 419 | } 420 | if (_unknownFields != null) { 421 | _unknownFields.WriteTo(ref output); 422 | } 423 | } 424 | #endif 425 | 426 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 427 | public int CalculateSize() { 428 | int size = 0; 429 | if (Name.Length != 0) { 430 | size += 1 + pb::CodedOutputStream.ComputeStringSize(Name); 431 | } 432 | if (UnitValue.Length != 0) { 433 | size += 1 + pb::CodedOutputStream.ComputeStringSize(UnitValue); 434 | } 435 | size += value_.CalculateSize(_repeated_value_codec); 436 | if (LessIsBetter != false) { 437 | size += 1 + 1; 438 | } 439 | if (_unknownFields != null) { 440 | size += _unknownFields.CalculateSize(); 441 | } 442 | return size; 443 | } 444 | 445 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 446 | public void MergeFrom(Metric other) { 447 | if (other == null) { 448 | return; 449 | } 450 | if (other.Name.Length != 0) { 451 | Name = other.Name; 452 | } 453 | if (other.UnitValue.Length != 0) { 454 | UnitValue = other.UnitValue; 455 | } 456 | value_.Add(other.value_); 457 | if (other.LessIsBetter != false) { 458 | LessIsBetter = other.LessIsBetter; 459 | } 460 | _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); 461 | } 462 | 463 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 464 | public void MergeFrom(pb::CodedInputStream input) { 465 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 466 | input.ReadRawMessage(this); 467 | #else 468 | uint tag; 469 | while ((tag = input.ReadTag()) != 0) { 470 | switch(tag) { 471 | default: 472 | _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); 473 | break; 474 | case 10: { 475 | Name = input.ReadString(); 476 | break; 477 | } 478 | case 18: { 479 | UnitValue = input.ReadString(); 480 | break; 481 | } 482 | case 26: { 483 | value_.AddEntriesFrom(input, _repeated_value_codec); 484 | break; 485 | } 486 | case 32: { 487 | LessIsBetter = input.ReadBool(); 488 | break; 489 | } 490 | } 491 | } 492 | #endif 493 | } 494 | 495 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 496 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 497 | void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { 498 | uint tag; 499 | while ((tag = input.ReadTag()) != 0) { 500 | switch(tag) { 501 | default: 502 | _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); 503 | break; 504 | case 10: { 505 | Name = input.ReadString(); 506 | break; 507 | } 508 | case 18: { 509 | UnitValue = input.ReadString(); 510 | break; 511 | } 512 | case 26: { 513 | value_.AddEntriesFrom(ref input, _repeated_value_codec); 514 | break; 515 | } 516 | case 32: { 517 | LessIsBetter = input.ReadBool(); 518 | break; 519 | } 520 | } 521 | } 522 | } 523 | #endif 524 | 525 | } 526 | 527 | #endregion 528 | 529 | 530 | #endregion Designer generated code 531 | -------------------------------------------------------------------------------- /Recommendations/Contracts/Experiment.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Generated by the protocol buffer compiler. DO NOT EDIT! 3 | // source: Experiment.proto 4 | // 5 | #pragma warning disable 1591, 0612, 3021 6 | #region Designer generated code 7 | 8 | using pb = global::Google.Protobuf; 9 | using pbc = global::Google.Protobuf.Collections; 10 | using pbr = global::Google.Protobuf.Reflection; 11 | using scg = global::System.Collections.Generic; 12 | /// Holder for reflection information generated from Experiment.proto 13 | public static partial class ExperimentReflection { 14 | 15 | #region Descriptor 16 | /// File descriptor for Experiment.proto 17 | public static pbr::FileDescriptor Descriptor { 18 | get { return descriptor; } 19 | } 20 | private static pbr::FileDescriptor descriptor; 21 | 22 | static ExperimentReflection() { 23 | byte[] descriptorData = global::System.Convert.FromBase64String( 24 | string.Concat( 25 | "ChBFeHBlcmltZW50LnByb3RvGh9nb29nbGUvcHJvdG9idWYvdGltZXN0YW1w", 26 | "LnByb3RvGgxNZXRyaWMucHJvdG8aFFJlY29tbWVuZGF0aW9uLnByb3RvIogD", 27 | "CgpFeHBlcmltZW50EgoKAmlkGAEgASgJEgwKBG5hbWUYAiABKAkSGwoTZGVz", 28 | "Y3JpcHRpb25fY29udHJvbBgDIAEoCRIgCg9tZXRyaWNzX2NvbnRyb2wYBCAD", 29 | "KAsyBy5NZXRyaWMSIgoRbWV0cmljc190cmVhdG1lbnQYBSADKAsyBy5NZXRy", 30 | "aWMSKwoHY3JlYXRlZBgGIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3Rh", 31 | "bXASLQoJY29tcGxldGVkGAcgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVz", 32 | "dGFtcBIiCgZzdGF0dXMYCCABKA4yEi5FeHBlcmltZW50LlN0YXR1cxIdChVk", 33 | "ZXNjcmlwdGlvbl90cmVhdG1lbnQYCSABKAkSKAoPcmVjb21tZW5kYXRpb25z", 34 | "GAogAygLMg8uUmVjb21tZW5kYXRpb24iNAoGU3RhdHVzEg8KC05PVF9TVEFS", 35 | "VEVEEAASCgoGQUNUSVZFEAESDQoJQ09NUExFVEVEEAJiBnByb3RvMw==")); 36 | descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, 37 | new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.TimestampReflection.Descriptor, global::MetricReflection.Descriptor, global::RecommendationReflection.Descriptor, }, 38 | new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { 39 | new pbr::GeneratedClrTypeInfo(typeof(global::Experiment), global::Experiment.Parser, new[]{ "Id", "Name", "DescriptionControl", "MetricsControl", "MetricsTreatment", "Created", "Completed", "Status", "DescriptionTreatment", "Recommendations" }, null, new[]{ typeof(global::Experiment.Types.Status) }, null, null) 40 | })); 41 | } 42 | #endregion 43 | 44 | } 45 | #region Messages 46 | public sealed partial class Experiment : pb::IMessage 47 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 48 | , pb::IBufferMessage 49 | #endif 50 | { 51 | private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Experiment()); 52 | private pb::UnknownFieldSet _unknownFields; 53 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 54 | public static pb::MessageParser Parser { get { return _parser; } } 55 | 56 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 57 | public static pbr::MessageDescriptor Descriptor { 58 | get { return global::ExperimentReflection.Descriptor.MessageTypes[0]; } 59 | } 60 | 61 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 62 | pbr::MessageDescriptor pb::IMessage.Descriptor { 63 | get { return Descriptor; } 64 | } 65 | 66 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 67 | public Experiment() { 68 | OnConstruction(); 69 | } 70 | 71 | partial void OnConstruction(); 72 | 73 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 74 | public Experiment(Experiment other) : this() { 75 | id_ = other.id_; 76 | name_ = other.name_; 77 | descriptionControl_ = other.descriptionControl_; 78 | metricsControl_ = other.metricsControl_.Clone(); 79 | metricsTreatment_ = other.metricsTreatment_.Clone(); 80 | created_ = other.created_ != null ? other.created_.Clone() : null; 81 | completed_ = other.completed_ != null ? other.completed_.Clone() : null; 82 | status_ = other.status_; 83 | descriptionTreatment_ = other.descriptionTreatment_; 84 | recommendations_ = other.recommendations_.Clone(); 85 | _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); 86 | } 87 | 88 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 89 | public Experiment Clone() { 90 | return new Experiment(this); 91 | } 92 | 93 | /// Field number for the "id" field. 94 | public const int IdFieldNumber = 1; 95 | private string id_ = ""; 96 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 97 | public string Id { 98 | get { return id_; } 99 | set { 100 | id_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); 101 | } 102 | } 103 | 104 | /// Field number for the "name" field. 105 | public const int NameFieldNumber = 2; 106 | private string name_ = ""; 107 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 108 | public string Name { 109 | get { return name_; } 110 | set { 111 | name_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); 112 | } 113 | } 114 | 115 | /// Field number for the "description_control" field. 116 | public const int DescriptionControlFieldNumber = 3; 117 | private string descriptionControl_ = ""; 118 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 119 | public string DescriptionControl { 120 | get { return descriptionControl_; } 121 | set { 122 | descriptionControl_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); 123 | } 124 | } 125 | 126 | /// Field number for the "metrics_control" field. 127 | public const int MetricsControlFieldNumber = 4; 128 | private static readonly pb::FieldCodec _repeated_metricsControl_codec 129 | = pb::FieldCodec.ForMessage(34, global::Metric.Parser); 130 | private readonly pbc::RepeatedField metricsControl_ = new pbc::RepeatedField(); 131 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 132 | public pbc::RepeatedField MetricsControl { 133 | get { return metricsControl_; } 134 | } 135 | 136 | /// Field number for the "metrics_treatment" field. 137 | public const int MetricsTreatmentFieldNumber = 5; 138 | private static readonly pb::FieldCodec _repeated_metricsTreatment_codec 139 | = pb::FieldCodec.ForMessage(42, global::Metric.Parser); 140 | private readonly pbc::RepeatedField metricsTreatment_ = new pbc::RepeatedField(); 141 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 142 | public pbc::RepeatedField MetricsTreatment { 143 | get { return metricsTreatment_; } 144 | } 145 | 146 | /// Field number for the "created" field. 147 | public const int CreatedFieldNumber = 6; 148 | private global::Google.Protobuf.WellKnownTypes.Timestamp created_; 149 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 150 | public global::Google.Protobuf.WellKnownTypes.Timestamp Created { 151 | get { return created_; } 152 | set { 153 | created_ = value; 154 | } 155 | } 156 | 157 | /// Field number for the "completed" field. 158 | public const int CompletedFieldNumber = 7; 159 | private global::Google.Protobuf.WellKnownTypes.Timestamp completed_; 160 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 161 | public global::Google.Protobuf.WellKnownTypes.Timestamp Completed { 162 | get { return completed_; } 163 | set { 164 | completed_ = value; 165 | } 166 | } 167 | 168 | /// Field number for the "status" field. 169 | public const int StatusFieldNumber = 8; 170 | private global::Experiment.Types.Status status_ = global::Experiment.Types.Status.NotStarted; 171 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 172 | public global::Experiment.Types.Status Status { 173 | get { return status_; } 174 | set { 175 | status_ = value; 176 | } 177 | } 178 | 179 | /// Field number for the "description_treatment" field. 180 | public const int DescriptionTreatmentFieldNumber = 9; 181 | private string descriptionTreatment_ = ""; 182 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 183 | public string DescriptionTreatment { 184 | get { return descriptionTreatment_; } 185 | set { 186 | descriptionTreatment_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); 187 | } 188 | } 189 | 190 | /// Field number for the "recommendations" field. 191 | public const int RecommendationsFieldNumber = 10; 192 | private static readonly pb::FieldCodec _repeated_recommendations_codec 193 | = pb::FieldCodec.ForMessage(82, global::Recommendation.Parser); 194 | private readonly pbc::RepeatedField recommendations_ = new pbc::RepeatedField(); 195 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 196 | public pbc::RepeatedField Recommendations { 197 | get { return recommendations_; } 198 | } 199 | 200 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 201 | public override bool Equals(object other) { 202 | return Equals(other as Experiment); 203 | } 204 | 205 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 206 | public bool Equals(Experiment other) { 207 | if (ReferenceEquals(other, null)) { 208 | return false; 209 | } 210 | if (ReferenceEquals(other, this)) { 211 | return true; 212 | } 213 | if (Id != other.Id) return false; 214 | if (Name != other.Name) return false; 215 | if (DescriptionControl != other.DescriptionControl) return false; 216 | if(!metricsControl_.Equals(other.metricsControl_)) return false; 217 | if(!metricsTreatment_.Equals(other.metricsTreatment_)) return false; 218 | if (!object.Equals(Created, other.Created)) return false; 219 | if (!object.Equals(Completed, other.Completed)) return false; 220 | if (Status != other.Status) return false; 221 | if (DescriptionTreatment != other.DescriptionTreatment) return false; 222 | if(!recommendations_.Equals(other.recommendations_)) return false; 223 | return Equals(_unknownFields, other._unknownFields); 224 | } 225 | 226 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 227 | public override int GetHashCode() { 228 | int hash = 1; 229 | if (Id.Length != 0) hash ^= Id.GetHashCode(); 230 | if (Name.Length != 0) hash ^= Name.GetHashCode(); 231 | if (DescriptionControl.Length != 0) hash ^= DescriptionControl.GetHashCode(); 232 | hash ^= metricsControl_.GetHashCode(); 233 | hash ^= metricsTreatment_.GetHashCode(); 234 | if (created_ != null) hash ^= Created.GetHashCode(); 235 | if (completed_ != null) hash ^= Completed.GetHashCode(); 236 | if (Status != global::Experiment.Types.Status.NotStarted) hash ^= Status.GetHashCode(); 237 | if (DescriptionTreatment.Length != 0) hash ^= DescriptionTreatment.GetHashCode(); 238 | hash ^= recommendations_.GetHashCode(); 239 | if (_unknownFields != null) { 240 | hash ^= _unknownFields.GetHashCode(); 241 | } 242 | return hash; 243 | } 244 | 245 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 246 | public override string ToString() { 247 | return pb::JsonFormatter.ToDiagnosticString(this); 248 | } 249 | 250 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 251 | public void WriteTo(pb::CodedOutputStream output) { 252 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 253 | output.WriteRawMessage(this); 254 | #else 255 | if (Id.Length != 0) { 256 | output.WriteRawTag(10); 257 | output.WriteString(Id); 258 | } 259 | if (Name.Length != 0) { 260 | output.WriteRawTag(18); 261 | output.WriteString(Name); 262 | } 263 | if (DescriptionControl.Length != 0) { 264 | output.WriteRawTag(26); 265 | output.WriteString(DescriptionControl); 266 | } 267 | metricsControl_.WriteTo(output, _repeated_metricsControl_codec); 268 | metricsTreatment_.WriteTo(output, _repeated_metricsTreatment_codec); 269 | if (created_ != null) { 270 | output.WriteRawTag(50); 271 | output.WriteMessage(Created); 272 | } 273 | if (completed_ != null) { 274 | output.WriteRawTag(58); 275 | output.WriteMessage(Completed); 276 | } 277 | if (Status != global::Experiment.Types.Status.NotStarted) { 278 | output.WriteRawTag(64); 279 | output.WriteEnum((int) Status); 280 | } 281 | if (DescriptionTreatment.Length != 0) { 282 | output.WriteRawTag(74); 283 | output.WriteString(DescriptionTreatment); 284 | } 285 | recommendations_.WriteTo(output, _repeated_recommendations_codec); 286 | if (_unknownFields != null) { 287 | _unknownFields.WriteTo(output); 288 | } 289 | #endif 290 | } 291 | 292 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 293 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 294 | void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { 295 | if (Id.Length != 0) { 296 | output.WriteRawTag(10); 297 | output.WriteString(Id); 298 | } 299 | if (Name.Length != 0) { 300 | output.WriteRawTag(18); 301 | output.WriteString(Name); 302 | } 303 | if (DescriptionControl.Length != 0) { 304 | output.WriteRawTag(26); 305 | output.WriteString(DescriptionControl); 306 | } 307 | metricsControl_.WriteTo(ref output, _repeated_metricsControl_codec); 308 | metricsTreatment_.WriteTo(ref output, _repeated_metricsTreatment_codec); 309 | if (created_ != null) { 310 | output.WriteRawTag(50); 311 | output.WriteMessage(Created); 312 | } 313 | if (completed_ != null) { 314 | output.WriteRawTag(58); 315 | output.WriteMessage(Completed); 316 | } 317 | if (Status != global::Experiment.Types.Status.NotStarted) { 318 | output.WriteRawTag(64); 319 | output.WriteEnum((int) Status); 320 | } 321 | if (DescriptionTreatment.Length != 0) { 322 | output.WriteRawTag(74); 323 | output.WriteString(DescriptionTreatment); 324 | } 325 | recommendations_.WriteTo(ref output, _repeated_recommendations_codec); 326 | if (_unknownFields != null) { 327 | _unknownFields.WriteTo(ref output); 328 | } 329 | } 330 | #endif 331 | 332 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 333 | public int CalculateSize() { 334 | int size = 0; 335 | if (Id.Length != 0) { 336 | size += 1 + pb::CodedOutputStream.ComputeStringSize(Id); 337 | } 338 | if (Name.Length != 0) { 339 | size += 1 + pb::CodedOutputStream.ComputeStringSize(Name); 340 | } 341 | if (DescriptionControl.Length != 0) { 342 | size += 1 + pb::CodedOutputStream.ComputeStringSize(DescriptionControl); 343 | } 344 | size += metricsControl_.CalculateSize(_repeated_metricsControl_codec); 345 | size += metricsTreatment_.CalculateSize(_repeated_metricsTreatment_codec); 346 | if (created_ != null) { 347 | size += 1 + pb::CodedOutputStream.ComputeMessageSize(Created); 348 | } 349 | if (completed_ != null) { 350 | size += 1 + pb::CodedOutputStream.ComputeMessageSize(Completed); 351 | } 352 | if (Status != global::Experiment.Types.Status.NotStarted) { 353 | size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Status); 354 | } 355 | if (DescriptionTreatment.Length != 0) { 356 | size += 1 + pb::CodedOutputStream.ComputeStringSize(DescriptionTreatment); 357 | } 358 | size += recommendations_.CalculateSize(_repeated_recommendations_codec); 359 | if (_unknownFields != null) { 360 | size += _unknownFields.CalculateSize(); 361 | } 362 | return size; 363 | } 364 | 365 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 366 | public void MergeFrom(Experiment other) { 367 | if (other == null) { 368 | return; 369 | } 370 | if (other.Id.Length != 0) { 371 | Id = other.Id; 372 | } 373 | if (other.Name.Length != 0) { 374 | Name = other.Name; 375 | } 376 | if (other.DescriptionControl.Length != 0) { 377 | DescriptionControl = other.DescriptionControl; 378 | } 379 | metricsControl_.Add(other.metricsControl_); 380 | metricsTreatment_.Add(other.metricsTreatment_); 381 | if (other.created_ != null) { 382 | if (created_ == null) { 383 | Created = new global::Google.Protobuf.WellKnownTypes.Timestamp(); 384 | } 385 | Created.MergeFrom(other.Created); 386 | } 387 | if (other.completed_ != null) { 388 | if (completed_ == null) { 389 | Completed = new global::Google.Protobuf.WellKnownTypes.Timestamp(); 390 | } 391 | Completed.MergeFrom(other.Completed); 392 | } 393 | if (other.Status != global::Experiment.Types.Status.NotStarted) { 394 | Status = other.Status; 395 | } 396 | if (other.DescriptionTreatment.Length != 0) { 397 | DescriptionTreatment = other.DescriptionTreatment; 398 | } 399 | recommendations_.Add(other.recommendations_); 400 | _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); 401 | } 402 | 403 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 404 | public void MergeFrom(pb::CodedInputStream input) { 405 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 406 | input.ReadRawMessage(this); 407 | #else 408 | uint tag; 409 | while ((tag = input.ReadTag()) != 0) { 410 | switch(tag) { 411 | default: 412 | _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); 413 | break; 414 | case 10: { 415 | Id = input.ReadString(); 416 | break; 417 | } 418 | case 18: { 419 | Name = input.ReadString(); 420 | break; 421 | } 422 | case 26: { 423 | DescriptionControl = input.ReadString(); 424 | break; 425 | } 426 | case 34: { 427 | metricsControl_.AddEntriesFrom(input, _repeated_metricsControl_codec); 428 | break; 429 | } 430 | case 42: { 431 | metricsTreatment_.AddEntriesFrom(input, _repeated_metricsTreatment_codec); 432 | break; 433 | } 434 | case 50: { 435 | if (created_ == null) { 436 | Created = new global::Google.Protobuf.WellKnownTypes.Timestamp(); 437 | } 438 | input.ReadMessage(Created); 439 | break; 440 | } 441 | case 58: { 442 | if (completed_ == null) { 443 | Completed = new global::Google.Protobuf.WellKnownTypes.Timestamp(); 444 | } 445 | input.ReadMessage(Completed); 446 | break; 447 | } 448 | case 64: { 449 | Status = (global::Experiment.Types.Status) input.ReadEnum(); 450 | break; 451 | } 452 | case 74: { 453 | DescriptionTreatment = input.ReadString(); 454 | break; 455 | } 456 | case 82: { 457 | recommendations_.AddEntriesFrom(input, _repeated_recommendations_codec); 458 | break; 459 | } 460 | } 461 | } 462 | #endif 463 | } 464 | 465 | #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE 466 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 467 | void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { 468 | uint tag; 469 | while ((tag = input.ReadTag()) != 0) { 470 | switch(tag) { 471 | default: 472 | _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); 473 | break; 474 | case 10: { 475 | Id = input.ReadString(); 476 | break; 477 | } 478 | case 18: { 479 | Name = input.ReadString(); 480 | break; 481 | } 482 | case 26: { 483 | DescriptionControl = input.ReadString(); 484 | break; 485 | } 486 | case 34: { 487 | metricsControl_.AddEntriesFrom(ref input, _repeated_metricsControl_codec); 488 | break; 489 | } 490 | case 42: { 491 | metricsTreatment_.AddEntriesFrom(ref input, _repeated_metricsTreatment_codec); 492 | break; 493 | } 494 | case 50: { 495 | if (created_ == null) { 496 | Created = new global::Google.Protobuf.WellKnownTypes.Timestamp(); 497 | } 498 | input.ReadMessage(Created); 499 | break; 500 | } 501 | case 58: { 502 | if (completed_ == null) { 503 | Completed = new global::Google.Protobuf.WellKnownTypes.Timestamp(); 504 | } 505 | input.ReadMessage(Completed); 506 | break; 507 | } 508 | case 64: { 509 | Status = (global::Experiment.Types.Status) input.ReadEnum(); 510 | break; 511 | } 512 | case 74: { 513 | DescriptionTreatment = input.ReadString(); 514 | break; 515 | } 516 | case 82: { 517 | recommendations_.AddEntriesFrom(ref input, _repeated_recommendations_codec); 518 | break; 519 | } 520 | } 521 | } 522 | } 523 | #endif 524 | 525 | #region Nested types 526 | /// Container for nested types declared in the Experiment message type. 527 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute] 528 | public static partial class Types { 529 | public enum Status { 530 | [pbr::OriginalName("NOT_STARTED")] NotStarted = 0, 531 | [pbr::OriginalName("ACTIVE")] Active = 1, 532 | [pbr::OriginalName("COMPLETED")] Completed = 2, 533 | } 534 | 535 | } 536 | #endregion 537 | 538 | } 539 | 540 | #endregion 541 | 542 | 543 | #endregion Designer generated code 544 | --------------------------------------------------------------------------------