{"id":466,"date":"2021-06-24T07:47:01","date_gmt":"2021-06-24T07:47:01","guid":{"rendered":"https:\/\/michaeljohnsteiner.com\/?p=466"},"modified":"2021-06-24T07:47:01","modified_gmt":"2021-06-24T07:47:01","slug":"segmentedarray-cs","status":"publish","type":"post","link":"https:\/\/michaeljohnsteiner.com\/index.php\/2021\/06\/24\/segmentedarray-cs\/","title":{"rendered":"SegmentedArray.cs"},"content":{"rendered":"\n<p>Segmented Array Class<\/p>\n\n\n\n<p>I wrote this array class while investigating the error curve in Prime Number Theorem. I wanted to avoid using blocking while using parallel invoke, while using as little memory as possible.<\/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;\npublic struct SegmentedArray&lt;T>\n{\n    private readonly IntA&lt;T>[] _array;\n    private readonly int       _size;\n    public SegmentedArray(int length, int size)\n    {\n        _array = new IntA&lt;T>[16];\n        _size  = size;\n    }\n    public void Add(T item, int index, long range, long total)\n    {\n        if (!_array[index].Allocated)\n            _array[index] = new IntA&lt;T>(_size);\n        var density = (float)_array[index].Count \/ range;\n        var ssic    = total                      * density;\n        _array[index].Add(item, (int)ssic);\n    }\n    public T[] ToArray()\n    {\n        var totalCount = 0;\n        for (var i = 0; i &lt; 16; ++i)\n            if (_array[i].Allocated)\n                totalCount += _array[i].Count;\n        var ta  = new T[totalCount];\n        var ptr = 0;\n        for (var i = 0; i &lt; 16; ++i)\n            if (_array[i].Allocated)\n            {\n                var it = _array[i].ToArray();\n                _array[i].Zero();\n                for (var j = 0; j &lt; it.Length; ++j)\n                    ta[ptr++] = it[j];\n            }\n        return ta;\n    }\n    [DebuggerDisplay(\"Count = {Count}\")]\n    internal struct IntA&lt;T> : IEnumerable&lt;T>\n    {\n        internal T[]  _array;\n        internal bool Allocated;\n        public IntA(int cap)\n        {\n            Count     = 0;\n            _array    = new T[cap];\n            Allocated = true;\n        }\n        public int Count\n        {\n            get;\n            private set;\n        }\n        public T this[int index]\n        {\n            get\n            {\n                if (index > _array.Length)\n                    throw new Exception(\"Error: Index out of range.\");\n                return _array[index];\n            }\n            set\n            {\n                if (index > _array.Length)\n                    throw new Exception(\"Error: Index out of range.\");\n                _array[index] = value;\n            }\n        }\n        IEnumerator&lt;T> IEnumerable&lt;T>.GetEnumerator()\n        {\n            return GetEnumerator();\n        }\n        IEnumerator IEnumerable.GetEnumerator()\n        {\n            return GetEnumerator();\n        }\n        public void Add(T item, int suggestedSize)\n        {\n            if (Count >= _array.Length)\n                Array.Resize(ref _array, suggestedSize);\n            _array[Count] = item;\n            Count++;\n        }\n        public T[] ToArray()\n        {\n            var newtArray = new T[Count];\n            Array.Copy(_array, 0, newtArray, 0, Count);\n            return newtArray;\n        }\n        public void Clean()\n        {\n            var newtArray = new T[Count];\n            Array.Copy(_array, 0, newtArray, 0, Count);\n            _array = newtArray;\n        }\n        public void Clear()\n        {\n            Array.Clear(_array, 0, Count);\n            Count = 0;\n        }\n        public void Zero()\n        {\n            _array = Array.Empty&lt;T>();\n            Count  = 0;\n        }\n        public IEnumerator&lt;T> GetEnumerator()\n        {\n            return GetEnum();\n        }\n        public IEnumerator&lt;T> GetEnum()\n        {\n            for (var i = 0; i &lt; Count; i++)\n                yield return _array[i];\n        }\n    }\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Segmented Array Class I wrote this array class while investigating the error curve in Prime Number Theorem. I wanted to avoid using blocking while using parallel invoke, while using as little memory as possible.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[2],"tags":[35,192,191,68],"_links":{"self":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/466"}],"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=466"}],"version-history":[{"count":1,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/466\/revisions"}],"predecessor-version":[{"id":467,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/466\/revisions\/467"}],"wp:attachment":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/media?parent=466"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/categories?post=466"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/tags?post=466"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}