{"id":389,"date":"2021-03-17T05:59:38","date_gmt":"2021-03-17T05:59:38","guid":{"rendered":"https:\/\/michaeljohnsteiner.com\/?p=389"},"modified":"2021-03-17T06:05:28","modified_gmt":"2021-03-17T06:05:28","slug":"acdictionary-cs","status":"publish","type":"post","link":"https:\/\/michaeljohnsteiner.com\/index.php\/2021\/03\/17\/acdictionary-cs\/","title":{"rendered":"AcDictionary.cs"},"content":{"rendered":"\n<p>Support Dictionary for Hash Mapping<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics;\n[DebuggerDisplay(\"Count = {Count}\")]\n[Serializable]\npublic class AcDictionary&lt;TKey, TValue> : MonitorActionFuncWrapper, IEnumerable&lt;KeyValuePair&lt;TKey, TValue>>\n{\n    public MSet15&lt;TKey> _keys;\n    public TValue[]     _values;\n    public AcDictionary() : this(101, EqualityComparer&lt;TKey>.Default)\n    {\n    }\n    public AcDictionary(int size) : this(size, EqualityComparer&lt;TKey>.Default)\n    {\n    }\n    public AcDictionary(int size, IEqualityComparer&lt;TKey> comparer)\n    {\n        if (comparer == null)\n            comparer = EqualityComparer&lt;TKey>.Default;\n        _keys          = new MSet15&lt;TKey>(size);\n        _values        = new TValue[size];\n        _keys.Comparer = comparer;\n    }\n    public AcDictionary(IEnumerable&lt;KeyValuePair&lt;TKey, TValue>> collection, IEqualityComparer&lt;TKey> comparer = null)\n    {\n        if (comparer == null)\n            comparer = EqualityComparer&lt;TKey>.Default;\n        _keys.Comparer = comparer;\n        foreach (var kp in collection)\n            Add(kp.Key, kp.Value);\n    }\n    public int Count => _keys.Count;\n    public TValue this[TKey key]\n    {\n        get\n        {\n            var pos = _keys.FindEntry(key);\n            return pos == -1 ? default : _values[pos];\n        }\n        set => Add(key, value);\n    }\n    public TValue[]                     Values        => _values;\n    public KeyValuePair&lt;TKey, TValue>[] KeyValuePairs => ToArray();\n    public TKey[]                       Keys          => _keys.ToArray();\n    public IEnumerator&lt;KeyValuePair&lt;TKey, TValue>> GetEnumerator()\n    {\n        return Lock(this, () =>\n        {\n            return GetEnum();\n        });\n    }\n    IEnumerator IEnumerable.GetEnumerator()\n    {\n        return Lock(this, () =>\n        {\n            return GetEnum();\n        });\n    }\n    private IEnumerator&lt;KeyValuePair&lt;TKey, TValue>> GetEnum()\n    {\n        for (var i = 0; i &lt; Count; i++)\n            if (_keys.Slots[i].HashCode > 0)\n                yield return new KeyValuePair&lt;TKey, TValue>(_keys.Slots[i].Value, _values[i]);\n    }\n    public bool Add(TKey key, TValue value)\n    {\n        return Lock(this, () =>\n        {\n            if (!_keys.Add(key))\n            {\n                if (Values.Length != _keys.Slots.Length)\n                {\n                    var nValues = new TValue[_keys.Slots.Length];\n                    Array.Copy(_values, nValues, _values.Length);\n                    _values = nValues;\n                }\n                Values[_keys.Position] = value;\n                return false;\n            }\n            Values[_keys.Position] = value;\n            return true;\n        });\n    }\n    public void Remove(TKey key)\n    {\n        Lock(this, () =>\n        {\n            var pos = _keys.FindEntry(key);\n            if (pos != -1)\n            {\n                Values[pos] = default;\n                _keys.Remove(key);\n            }\n        });\n    }\n    public bool ContainsKey(TKey key)\n    {\n        return Lock(this, () =>\n        {\n            return _keys.FindEntry(key) != -1;\n        });\n    }\n    public bool ContainsValue(TValue value)\n    {\n        return Lock(this, () =>\n        {\n            var vab = value.GetBytes();\n            foreach (var v in _values)\n            {\n                if (v == null)\n                    continue;\n                var vab1 = v.GetBytes();\n                if (vab.Compare(vab1))\n                    return true;\n            }\n            return false;\n        });\n    }\n    public int FindKeyIndex(TKey key)\n    {\n        return Lock(this, () =>\n        {\n            return _keys.FindEntry(key);\n        });\n    }\n    public KeyValuePair&lt;TKey, TValue>[] ToArray()\n    {\n        return Lock(this, () =>\n        {\n            var array = new KeyValuePair&lt;TKey, TValue>[Count];\n            var idx   = 0;\n            foreach (var k in _keys)\n                if (_keys.FindEntry(k) != -1)\n                {\n                    var v = _values[_keys.Position];\n                    array[idx] = new KeyValuePair&lt;TKey, TValue>(k, v);\n                    idx++;\n                }\n            return array;\n        });\n    }\n    public void Clear()\n    {\n        Lock(this, () =>\n        {\n            _keys   = new MSet15&lt;TKey>(_keys.Slots.Length);\n            _values = new TValue[_keys.Slots.Length];\n        });\n    }\n}<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">[SecuritySafeCritical]\n    public static unsafe bool Compare(this byte[] a1, byte[] a2)\n    {\n        if (a1 == null &amp;&amp; a2 == null)\n            return true;\n        if (a1 == null || a2 == null || a1.Length != a2.Length)\n            return false;\n        fixed (byte* p1 = a1, p2 = a2)\n        {\n            var   Len = a1.Length;\n            byte* x1  = p1, x2 = p2;\n            while (Len > 7)\n            {\n                if (*(long*) x2 != *(long*) x1)\n                    return false;\n                x1  += 8;\n                x2  += 8;\n                Len -= 8;\n            }\n            switch (Len % 8)\n            {\n                case 0:\n                    break;\n                case 7:\n                    if (*(int*) x2 != *(int*) x1)\n                        return false;\n                    x1 += 4;\n                    x2 += 4;\n                    if (*(short*) x2 != *(short*) x1)\n                        return false;\n                    x1 += 2;\n                    x2 += 2;\n                    if (*x2 != *x1)\n                        return false;\n                    break;\n                case 6:\n                    if (*(int*) x2 != *(int*) x1)\n                        return false;\n                    x1 += 4;\n                    x2 += 4;\n                    if (*(short*) x2 != *(short*) x1)\n                        return false;\n                    break;\n                case 5:\n                    if (*(int*) x2 != *(int*) x1)\n                        return false;\n                    x1 += 4;\n                    x2 += 4;\n                    if (*x2 != *x1)\n                        return false;\n                    break;\n                case 4:\n                    if (*(int*) x2 != *(int*) x1)\n                        return false;\n                    break;\n                case 3:\n                    if (*(short*) x2 != *(short*) x1)\n                        return false;\n                    x1 += 2;\n                    x2 += 2;\n                    if (*x2 != *x1)\n                        return false;\n                    break;\n                case 2:\n                    if (*(short*) x2 != *(short*) x1)\n                        return false;\n                    break;\n                case 1:\n                    if (*x2 != *x1)\n                        return false;\n                    break;\n            }\n            return true;\n        }\n    }<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Support Dictionary for Hash Mapping<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[2],"tags":[84,59,87],"_links":{"self":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/389"}],"collection":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/comments?post=389"}],"version-history":[{"count":2,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/389\/revisions"}],"predecessor-version":[{"id":393,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/389\/revisions\/393"}],"wp:attachment":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/media?parent=389"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/categories?post=389"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/tags?post=389"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}