<commit_before>﻿using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using ClientSamples.CachingTools;

namespace Tavis.PrivateCache.InMemoryStore
{
    public class InMemoryContentStore : IContentStore
    {
        private readonly object syncRoot = new object();
        private readonly Dictionary<PrimaryCacheKey, InMemoryCacheEntry> _responseCache = new Dictionary<PrimaryCacheKey, InMemoryCacheEntry>();

        public async Task<CacheEntry> GetEntryAsync(PrimaryCacheKey cacheKey)
        {
            if (_responseCache.ContainsKey(cacheKey))
            {
                return _responseCache[cacheKey].CacheEntry;
            }
            return null;
        }

        public async Task<CacheContent> GetContentAsync(CacheEntry cacheEntry, string secondaryKey)
        {
            var inMemoryCacheEntry = _responseCache[cacheEntry.Key];
            if (inMemoryCacheEntry.Responses.ContainsKey(secondaryKey))
            {
                return await CloneAsync(inMemoryCacheEntry.Responses[secondaryKey]);
            }
            return null;
        }

        public async Task UpdateEntryAsync(CacheContent content)
        {
            CacheEntry entry = content.CacheEntry;

            InMemoryCacheEntry inMemoryCacheEntry = null;

            if (!_responseCache.ContainsKey(entry.Key))
            {
                inMemoryCacheEntry = new InMemoryCacheEntry(entry);
                lock (syncRoot)
                {
                    _responseCache[entry.Key] = inMemoryCacheEntry;
                }
            }
            else
            {
                inMemoryCacheEntry = _responseCache[entry.Key];
            }
            
            var newContent = await CloneAsync(content);
            lock (syncRoot)
            {
                inMemoryCacheEntry.Responses[content.Key] = newContent;
            }
        }


        private async Task<CacheContent> CloneAsync(CacheContent cacheContent)
        {
            var newResponse = await new HttpMessageContent(cacheContent.Response).ReadAsHttpResponseMessageAsync();

            var newContent = new CacheContent()
            {
                CacheEntry = cacheContent.CacheEntry,
                Key = cacheContent.Key,
                Expires = cacheContent.Expires,
                HasValidator = cacheContent.HasValidator,
                CacheControl = cacheContent.CacheControl,
                Response = newResponse
            };
            return newContent;
        }
    }

    public class InMemoryCacheEntry
    {
        public CacheEntry CacheEntry { get; set; }
        public Dictionary<string,CacheContent> Responses { get; set; }

        public InMemoryCacheEntry(CacheEntry cacheEntry)
        {
            CacheEntry = cacheEntry;
            Responses = new Dictionary<string, CacheContent>();
        }
    }
}<commit_msg>Get rid of the WebApi dependency<commit_after>﻿using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using ClientSamples.CachingTools;

namespace Tavis.PrivateCache.InMemoryStore
{
    public class InMemoryContentStore : IContentStore
    {
        private readonly object syncRoot = new object();
        private readonly Dictionary<PrimaryCacheKey, InMemoryCacheEntry> _responseCache = new Dictionary<PrimaryCacheKey, InMemoryCacheEntry>();

        public Task<CacheEntry> GetEntryAsync(PrimaryCacheKey cacheKey)
        {
            if (_responseCache.ContainsKey(cacheKey))
            {
                return Task.FromResult(_responseCache[cacheKey].CacheEntry);
            }

            return Task.FromResult(default(CacheEntry));
        }

        public async Task<CacheContent> GetContentAsync(CacheEntry cacheEntry, string secondaryKey)
        {
            var inMemoryCacheEntry = _responseCache[cacheEntry.Key];
            if (inMemoryCacheEntry.Responses.ContainsKey(secondaryKey))
            {
                return await CloneAsync(inMemoryCacheEntry.Responses[secondaryKey]);
            }

            return null;
        }

        public async Task UpdateEntryAsync(CacheContent content)
        {
            CacheEntry entry = content.CacheEntry;

            InMemoryCacheEntry inMemoryCacheEntry = null;

            if (!_responseCache.ContainsKey(entry.Key))
            {
                inMemoryCacheEntry = new InMemoryCacheEntry(entry);
                lock (syncRoot)
                {
                    _responseCache[entry.Key] = inMemoryCacheEntry;
                }
            }
            else
            {
                inMemoryCacheEntry = _responseCache[entry.Key];
            }
            
            var newContent = await CloneAsync(content);
            lock (syncRoot)
            {
                inMemoryCacheEntry.Responses[content.Key] = newContent;
            }
        }

        private async Task<CacheContent> CloneAsync(CacheContent cacheContent)
        {
            var newResponse = new HttpResponseMessage(cacheContent.Response.StatusCode);
            var ms = new MemoryStream();

            foreach (var v in newResponse.Headers) newResponse.Headers.TryAddWithoutValidation(v.Key, v.Value);
            await (await cacheContent.Response.Content.ReadAsStreamAsync().ConfigureAwait(false))
                .CopyToAsync(ms).ConfigureAwait(false);

            newResponse.Content = new StreamContent(ms);
            foreach (var v in newResponse.Content.Headers) newResponse.Content.Headers.TryAddWithoutValidation(v.Key, v.Value);

            var newContent = new CacheContent()
            {
                CacheEntry = cacheContent.CacheEntry,
                Key = cacheContent.Key,
                Expires = cacheContent.Expires,
                HasValidator = cacheContent.HasValidator,
                CacheControl = cacheContent.CacheControl,
                Response = newResponse
            };

            return newContent;
        }
    }

    public class InMemoryCacheEntry
    {
        public CacheEntry CacheEntry { get; set; }
        public Dictionary<string,CacheContent> Responses { get; set; }

        public InMemoryCacheEntry(CacheEntry cacheEntry)
        {
            CacheEntry = cacheEntry;
            Responses = new Dictionary<string, CacheContent>();
        }
    }
}
{'fraction_non_alphanumeric': 0.07102272727272728, 'fraction_numerical': 0.0, 'mean_word_length': 1.9681498829039812, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, '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': '2399217', 'n_tokens_mistral': 1539, 'n_tokens_neox': 1483, 'n_words': 304}