<commit_before>﻿using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;

namespace TemplateTable
{
    public class TemplateTable<TKey, TValue> : ITemplateTable<TKey>, IEnumerable<KeyValuePair<TKey, TValue>>
        where TKey : IComparable
        where TValue : class, new()
    {
        public class ValueData
        {
            public TValue Value;
            public Func<TKey, TValue> LazyLoader;
        }

        private ConcurrentDictionary<TKey, ValueData> _table =
            new ConcurrentDictionary<TKey, ValueData>();

        private ConcurrentDictionary<TKey, TValue> _ghostTable =
            new ConcurrentDictionary<TKey, TValue>();

        public Func<TKey, TValue> GhostValueFactory = null;

        public Type KeyType => typeof(TKey);

        public Type ValueType => typeof(TValue);

        public int Count => _table.Count;

        public TValue TryGet(TKey id)
        {
            ValueData data;
            if (_table.TryGetValue(id, out data) == false)
                return default(TValue);

            return data.Value ?? LoadLazyValue(id, data);
        }

        private TValue LoadLazyValue(TKey id, ValueData data)
        {
            var lazyLoader = data.LazyLoader;
            if (lazyLoader != null)
            {
                data.Value = data.LazyLoader(id);
                data.LazyLoader = null;
            }
            return data.Value;
        }

        public object TryGetValue(TKey id)
        {
            return TryGet(id);
        }

        public bool ContainsKey(TKey id)
        {
            return _table.ContainsKey(id);<commit_msg>Avoid race condition<commit_after>﻿using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;

namespace TemplateTable
{
    public class TemplateTable<TKey, TValue> : ITemplateTable<TKey>, IEnumerable<KeyValuePair<TKey, TValue>>
        where TKey : IComparable
        where TValue : class, new()
    {
        public class ValueData
        {
            public TValue Value;
            public Func<TKey, TValue> LazyLoader;
        }

        private ConcurrentDictionary<TKey, ValueData> _table =
            new ConcurrentDictionary<TKey, ValueData>();

        private ConcurrentDictionary<TKey, TValue> _ghostTable =
            new ConcurrentDictionary<TKey, TValue>();

        public Func<TKey, TValue> GhostValueFactory = null;

        public Type KeyType => typeof(TKey);

        public Type ValueType => typeof(TValue);

        public int Count => _table.Count;

        public TValue TryGet(TKey id)
        {
            ValueData data;
            if (_table.TryGetValue(id, out data) == false)
                return default(TValue);

            return data.Value ?? LoadLazyValue(id, data);
        }

        private TValue LoadLazyValue(TKey id, ValueData data)
        {
            var lazyLoader = data.LazyLoader;
            if (lazyLoader != null)
            {
                data.Value = lazyLoader(id);
                data.LazyLoader = null;
            }
            return data.Value;
        }

        public object TryGetValue(TKey id)
        {
            return TryGet(id);
        }

        public bool ContainsKey(TKey id)
        {
            return _table.ContainsKey(id);
{'fraction_non_alphanumeric': 0.08333333333333333, 'fraction_numerical': 0.0, 'mean_word_length': 1.9584805653710247, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 29, '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': '7230430', 'n_tokens_mistral': 923, 'n_tokens_neox': 896, 'n_words': 225}