public async Task <PredictionResponse> Predict(PredictionRequest predictionRequest) { var guid = Guid.NewGuid().ToString(); var predictionResponseItem = new PredictionResponseItem(); var response = new PredictionResponse(); var databaseContext = this.CreateContext(); var cache = await databaseContext.PredictionRequests.Where(g => g.Guid == guid).ToListAsync(); await this.InsertRequests(predictionRequest, guid); foreach (var loopItem in predictionRequest.Items) { predictionResponseItem = new PredictionResponseItem(); await CalculateProbability(loopItem, predictionResponseItem); response.Predictions.Add(predictionResponseItem); } // Experiment if (this.serviceConfiguration.ExperimentEnabled) { await this.InsertFilePredictionForExperiment(predictionRequest, guid); response = await this.FilterResponseForExperiment(predictionRequest, response); } return(response); }
private async Task <PredictionResponse> FilterResponseForFileMode(PredictionRequest request, PredictionResponse response) { using (var databaseContext = this.CreateContext()) { var index = 0; foreach (var item in request.Items) { var filePrediction = await databaseContext.FilePredictions .Where(file => file.FileName == item.Path) .SingleOrDefaultAsync(); if (filePrediction == null) { return(response); } if (filePrediction.PredictionEnabled) { response.Predictions[index].SuccessProbability = null; response.Predictions[index].ProbableSuccess = null; } index++; } } return(response); }
private async Task InsertRequests(PredictionRequest predictionRequest, string guid) { using (var databaseContext = this.CreateContext()) { foreach (var loopItem in predictionRequest.Items) { var requestCache = databaseContext.PredictionRequests.Create(); requestCache.Guid = guid; requestCache.Author = loopItem.Author; requestCache.Path = loopItem.Path; requestCache.OldPath = loopItem.OldPath; requestCache.NumberOfDistinctCommitters = loopItem.NumberOfDistinctCommitters; requestCache.NumberOfModifiedLines = loopItem.NumberOfModifiedLines; requestCache.NumberOfRevisions = loopItem.NumberOfRevisions; requestCache.TotalNumberOfRevisions = loopItem.TotalNumberOfRevisions; requestCache.PreviousBuildResult = loopItem.PreviousBuildResult; requestCache.ProjectName = predictionRequest.ProjectName; requestCache.CCMMd = loopItem.CCMMd; requestCache.CCMAvg = loopItem.CCMAvg; requestCache.CCMMax = loopItem.CCMMax; requestCache.CreatedAtUtc = DateTime.UtcNow; databaseContext.PredictionRequests.Add(requestCache); } await databaseContext.SaveChangesAsync(); } }
public char?GetNextBlockChar(PredictionRequest predictionRequest, BlockGenerationMode mode) { string developer = GetDeveloperName(predictionRequest); // MaxOccurrencesOfCharacterInBlock = 1 - random block generator. // MaxOccurrencesOfCharacterInBlock > 1 - alternating tratments design. const int MaxOccurrencesOfCharacterInBlock = 2; using (var databaseContext = this.CreateContext()) { var lastRbgData = GetLastRbgDatas(databaseContext, developer, MaxOccurrencesOfCharacterInBlock); int experimentDay = CalculateCurrentExperimentDay(lastRbgData); // Do nothing if we have RBG data for current experiment day. if (lastRbgData.Any() && experimentDay == lastRbgData[0].ExperimentDay) { return(lastRbgData[0].Mode[0]); } // Calculate for new day. char?nextCharacterInBlock = null; if (mode == BlockGenerationMode.RandomBlockGenerator) { // [0] 2018-01-05 JOHN A // [1] 2018-01-04 JOHN B // [2] 2018-01-03 JOHN A // [3] 2018-01-02 JOHN B var block = lastRbgData .Select(g => g.Mode[0]) .Reverse() .ToArray(); var blockGenerator = RandomBlockGenerator.Create(new[] { 'A', 'B' }); blockGenerator.SetBlock(block); // block = { 'B', 'A', 'B', 'A' } nextCharacterInBlock = blockGenerator.Next(MaxOccurrencesOfCharacterInBlock); } else if (mode == BlockGenerationMode.ImposedParticipant) { Participant participant = GetParticipant(developer, databaseContext); if (participant != null) { var generator = new ImposedBlockGenerator(); generator.SetBlock(participant.Block.ToList()); generator.SetPosition(experimentDay); nextCharacterInBlock = generator.GetForIndex(generator.Position); } } AppendRbgData(databaseContext, developer, experimentDay, nextCharacterInBlock); return(nextCharacterInBlock); } }
private static string GetDeveloperName(PredictionRequest predictionRequest) { string developer = "Unknown"; foreach (PredictionRequestFile reqf in predictionRequest.Items) { developer = reqf.Author; } return(developer); }
public async Task <PredictionRequest> Prepare(PredictionRequest predictionRequest) { if (predictionRequest?.Items == null) { return(predictionRequest); } var paths = predictionRequest.Items.Select(g => g.Path).ToList(); if (!paths.Any()) { return(predictionRequest); } var oldPaths = predictionRequest.Items.Select(g => g.OldPath).ToList(); Dictionary <string, Metric> lastStats; using (var context = new DatabaseContext(this.configuration.ExportDatabaseConnectionString)) { var query = context.Metrics; // Find last statistics for specified paths. var subquery = query.Where(g => paths.Contains(g.Path) || oldPaths.Contains(g.Path)) .GroupBy(g => g.Path) .Select(g => new { Path = g.Key, LastStat = g.OrderByDescending(p => p.BuildCommitDateTimeLocal).Select(p => p).FirstOrDefault() }); var result = await subquery.ToListAsync(); lastStats = result.ToDictionary(g => g.Path, g => g.LastStat); } foreach (var loopItem in predictionRequest.Items) { Metric stat; if (lastStats.TryGetValue(loopItem.Path, out stat)) { UpdatePrediction(loopItem, stat); } else if (lastStats.TryGetValue(loopItem.OldPath, out stat)) { UpdatePrediction(loopItem, stat); } } return(predictionRequest); }
private PredictionResponse FilterResponseForParticipantMode(PredictionRequest request, PredictionResponse response) { var result = this.rbgService.GetNextBlockChar(request, BlockGenerationMode.ImposedParticipant); if (result == 'B') { foreach (var prediction in response.Predictions) { prediction.SuccessProbability = null; prediction.ProbableSuccess = null; } } return(response); }
// Experimental setup private async Task <PredictionResponse> FilterResponseForExperiment(PredictionRequest request, PredictionResponse response) { if (!this.serviceConfiguration.ExperimentEnabled) { return(response); } switch (this.serviceConfiguration.ExperimentMode) { case ExperimentMode.Participant: return(this.FilterResponseForParticipantMode(request, response)); case ExperimentMode.File: return(await this.FilterResponseForFileMode(request, response)); } return(response); }
private async Task InsertFilePredictionForExperiment(PredictionRequest predictionRequest, string guid) { using (var databaseContext = this.CreateContext()) { foreach (var item in predictionRequest.Items) { var filePrediction = await databaseContext.FilePredictions .Where(file => file.FileName == item.Path) .SingleOrDefaultAsync(); if (filePrediction == null) { var fileCache = databaseContext.FilePredictions.Create(); fileCache.FileName = item.Path; fileCache.PredictionEnabled = this.rbgService.GetRandomPredictionEnabledFlag(); databaseContext.FilePredictions.Add(fileCache); } } await databaseContext.SaveChangesAsync(); } }
private async Task <PredictionResponse> GenerateResponse(PredictionRequest predictionRequest, string guid) { using (var databaseContext = this.CreateContext()) { var cache = await databaseContext.PredictionRequests.Where(g => g.Guid == guid).ToListAsync(); var response = new PredictionResponse(); foreach (var requestItem in predictionRequest.Items) { var cachedItem = cache.FirstOrDefault(g => g.Path == requestItem.Path); if (cachedItem == null) { throw new ApplicationException($"Cached item for path '{requestItem.Path}' not found"); } var predictionResponseItem = new PredictionResponseItem(); predictionResponseItem.ProbableSuccess = cachedItem.BuildResultPredictionClass; predictionResponseItem.SuccessProbability = 1 - cachedItem.BuildResultFaildPrediction; response.Predictions.Add(predictionResponseItem); } return(response); } }