<commit_before>namespace Buddhabrot.Core.Boundary;

public sealed class QuadCache
{
    private readonly List<Quad> _nodes;
    private readonly Dictionary<(Quad SW, Quad NW, Quad NE, Quad SE), Quad> _dict = new();

    public QuadCache(List<Quad> nodes) => _nodes = nodes;

    public int Size => _dict.Count;
    public int NumCachedValuesUsed { get; private set; }

    public Quad MakeQuad(Quad sw, Quad nw, Quad ne, Quad se)
    {
        if (sw.IsLeaf &&
            sw == nw &&
            nw == ne &&
            ne == se)
        {
            return sw;
        }

        var key = (sw, nw, ne, se);
        if (!_dict.TryGetValue(key, out var quad))
        {
            var type = new TypeCount()
                .Count(sw.Type)
                .Count(nw.Type)
                .Count(ne.Type)
                .Count(se.Type)
                .DetermineType();
            
            var index = _nodes.Count;
            quad = new Quad(type, index);
            _nodes.Add(sw);
            _nodes.Add(nw);
            _nodes.Add(ne);
            _nodes.Add(se);

            _dict.Add(key, quad);
        }
        else
        {
            NumCachedValuesUsed++;
        }

        return quad;
    }

    private readonly struct TypeCount
    {
        private readonly int _borderCount = 0;
        private readonly int _filamentCount = 0;
        private readonly int _inSetCount = 0;

        public TypeCount()
        {
        }

        private TypeCount(int borderCount, int filamentCount, int inSetCount)
        {
            _borderCount = borderCount;
            _filamentCount = filamentCount;
            _inSetCount = inSetCount;
        }

        public TypeCount Count(RegionType type) =>
            type switch
            {
                RegionType.Border => new(_borderCount + 1, _filamentCount, _inSetCount),
                RegionType.Filament => new(_borderCount, _filamentCount + 1, _inSetCount),
                RegionType.InSet => new(_borderCount, _filamentCount, _inSetCount + 1),
                _ => this,
            };

        public RegionType DetermineType()
        {
            if (_borderCount == 0 && _filamentCount == 0 && _inSetCount == 0)
                return RegionType.Empty;

            if (_borderCount >= 2)
                return RegionType.Border;

            return _filamentCount >= _inSetCount ? RegionType.Filament : RegionType.InSet;
        }
    }
}<commit_msg>Fix for failing test<commit_after>namespace Buddhabrot.Core.Boundary;

public sealed class QuadCache
{
    private readonly List<Quad> _nodes;
    private readonly Dictionary<(Quad SW, Quad NW, Quad NE, Quad SE), Quad> _dict = new();

    public QuadCache(List<Quad> nodes) => _nodes = nodes;

    public int Size => _dict.Count;
    public int NumCachedValuesUsed { get; private set; }

    public Quad MakeQuad(Quad sw, Quad nw, Quad ne, Quad se)
    {
        if (sw.IsLeaf &&
            sw == nw &&
            nw == ne &&
            ne == se)
        {
            return sw;
        }

        var key = (sw, nw, ne, se);
        if (!_dict.TryGetValue(key, out var quad))
        {
            var type = new TypeCount()
                .Count(sw.Type)
                .Count(nw.Type)
                .Count(ne.Type)
                .Count(se.Type)
                .DetermineType();
            
            var index = _nodes.Count;
            quad = new Quad(type, index);
            _nodes.Add(sw);
            _nodes.Add(nw);
            _nodes.Add(ne);
            _nodes.Add(se);

            _dict.Add(key, quad);
        }
        else
        {
            NumCachedValuesUsed++;
        }

        return quad;
    }

    private readonly struct TypeCount
    {
        private readonly int _borderCount = 0;
        private readonly int _filamentCount = 0;
        private readonly int _inSetCount = 0;

        public TypeCount()
        {
        }

        private TypeCount(int borderCount, int filamentCount, int inSetCount)
        {
            _borderCount = borderCount;
            _filamentCount = filamentCount;
            _inSetCount = inSetCount;
        }

        public TypeCount Count(RegionType type) =>
            type switch
            {
                RegionType.Border => new(_borderCount + 1, _filamentCount, _inSetCount),
                RegionType.Filament => new(_borderCount, _filamentCount + 1, _inSetCount),
                RegionType.InSet => new(_borderCount, _filamentCount, _inSetCount + 1),
                _ => this,
            };

        public RegionType DetermineType()
        {
            if (_borderCount == 0 && _filamentCount == 0 && _inSetCount == 0)
                return RegionType.Empty;

            if (_borderCount >= _filamentCount && _borderCount >= _inSetCount)
                return RegionType.Border;

            return _filamentCount >= _inSetCount ? RegionType.Filament : RegionType.InSet;
        }
    }
}
{'fraction_non_alphanumeric': 0.09387011936071211, 'fraction_numerical': 0.0038438195427877805, 'mean_word_length': 1.5590062111801242, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 28, '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': '3820483', 'n_tokens_mistral': 1455, 'n_tokens_neox': 1348, 'n_words': 351}