<commit_before>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace MiniCover.HitServices
{
    public class HitTestMethod
    {
        private readonly object _lock = new object();

        public static HitTestMethod From(MethodBase testMethod, Uri currentDirectory)
        {
            return new HitTestMethod(testMethod.DeclaringType.Assembly.FullName,
testMethod.DeclaringType.FullName, testMethod.Name, currentDirectory.MakeRelativeUri(new Uri(testMethod.DeclaringType.Assembly.Location)).ToString(), 0,
new Dictionary<int, int>());
        }

        public HitTestMethod(string assemblyName,
            string className,
            string methodName,
            string assemblyLocation,
            int counter, IDictionary<int, int> hitedInstructions)
        {
            AssemblyName = assemblyName;
            ClassName = className;
            MethodName = methodName;
            AssemblyLocation = assemblyLocation;
            Counter = counter;
            HitedInstructions = hitedInstructions;
        }

        public string AssemblyName { get; }
        public string ClassName { get; }
        public string MethodName { get; }
        public string AssemblyLocation { get; }
        public int Counter { get; private set; }
        public IDictionary<int, int> HitedInstructions { get; }

        public void HasHit(int id)
        {
            lock (_lock)
            {
                Counter++;
                if (this.HitedInstructions.TryGetValue(id, out var count))
                {
                    this.HitedInstructions[id] = count + 1;
                }
                else
                {
                    this.HitedInstructions[id] = 1;
                }
            }
        }

        public bool HasBeenHitBy(int instructionId)
        {
            return this.HitedInstructions.ContainsKey(instructionId);
        }

        public static IEnumerable<HitTestMethod> MergeDuplicates(IEnumerable<HitTestMethod> source, int instructionId)
        {
            return source
                .GroupBy(h => new { h.AssemblyName, h.ClassName, h.MethodName, h.AssemblyLocation })
                .Select(g => new HitTestMethod(
                    g.Key.AssemblyName,
                    g.Key.ClassName,
                    g.Key.MethodName,
                    g.Key.AssemblyLocation,
                    g.Sum(h => h.HitedInstructions[instructionId]),
                    new Dictionary<int, int>()
                )).ToArray();
        }

        public void Serialize(Stream stream)
        {
            Dictionary<int, int> hits;
            lock (_lock)
                hits = this.HitedInstructions.ToDictionary(a => a.Key, a => a.Value);
            using (var binaryWriter = new BinaryWriter(stream, Encoding.UTF8, true))
            {
                binaryWriter.Write(ClassName);
                binaryWriter.Write(MethodName);
                binaryWriter.Write(AssemblyName);
                binaryWriter.Write(AssemblyLocation);
                binaryWriter.Write(Counter);
                binaryWriter.Write(HitedInstructions.Count);
                foreach (var hitedInstruction in hits)
                {
                    binaryWriter.Write(hitedInstruction.Key);<commit_msg>Revert "to remove the lock on the stream"<commit_after>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace MiniCover.HitServices
{
    public class HitTestMethod
    {
        private readonly object _lock = new object();

        public static HitTestMethod From(MethodBase testMethod, Uri currentDirectory)
        {
            return new HitTestMethod(testMethod.DeclaringType.Assembly.FullName,
testMethod.DeclaringType.FullName, testMethod.Name, currentDirectory.MakeRelativeUri(new Uri(testMethod.DeclaringType.Assembly.Location)).ToString(), 0,
new Dictionary<int, int>());
        }

        public HitTestMethod(string assemblyName,
            string className,
            string methodName,
            string assemblyLocation,
            int counter, IDictionary<int, int> hitedInstructions)
        {
            AssemblyName = assemblyName;
            ClassName = className;
            MethodName = methodName;
            AssemblyLocation = assemblyLocation;
            Counter = counter;
            HitedInstructions = hitedInstructions;
        }

        public string AssemblyName { get; }
        public string ClassName { get; }
        public string MethodName { get; }
        public string AssemblyLocation { get; }
        public int Counter { get; private set; }
        public IDictionary<int, int> HitedInstructions { get; }

        public void HasHit(int id)
        {
            lock (_lock)
            {
                Counter++;
                if (this.HitedInstructions.TryGetValue(id, out var count))
                {
                    this.HitedInstructions[id] = count + 1;
                }
                else
                {
                    this.HitedInstructions[id] = 1;
                }
            }
        }

        public bool HasBeenHitBy(int instructionId)
        {
            return this.HitedInstructions.ContainsKey(instructionId);
        }

        public static IEnumerable<HitTestMethod> MergeDuplicates(IEnumerable<HitTestMethod> source, int instructionId)
        {
            return source
                .GroupBy(h => new { h.AssemblyName, h.ClassName, h.MethodName, h.AssemblyLocation })
                .Select(g => new HitTestMethod(
                    g.Key.AssemblyName,
                    g.Key.ClassName,
                    g.Key.MethodName,
                    g.Key.AssemblyLocation,
                    g.Sum(h => h.HitedInstructions[instructionId]),
                    new Dictionary<int, int>()
                )).ToArray();
        }

        public void Serialize(Stream stream)
        {
            lock (_lock)
            using (var binaryWriter = new BinaryWriter(stream, Encoding.UTF8, true))
            {
                binaryWriter.Write(ClassName);
                binaryWriter.Write(MethodName);
                binaryWriter.Write(AssemblyName);
                binaryWriter.Write(AssemblyLocation);
                binaryWriter.Write(Counter);
                binaryWriter.Write(HitedInstructions.Count);
                foreach (var hitedInstruction in HitedInstructions)
                {
                    binaryWriter.Write(hitedInstruction.Key);
{'fraction_non_alphanumeric': 0.07954545454545454, 'fraction_numerical': 0.0012121212121212121, 'mean_word_length': 1.7515631513130472, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3509003', 'n_tokens_mistral': 1654, 'n_tokens_neox': 1563, 'n_words': 356}