Пример #1
0
        [Test, Ignore("broken")] // TODO
        public void CouldAppendSeries()
        {
            var sa = new AppendSeries <int, int>(DataBlock.Create());

            Assert.IsTrue(sa.TryAddLast(1, 1).Result);
            Assert.IsFalse(sa.TryAddLast(1, 1).Result);

            Assert.IsTrue(sa.TryAddLast(2, 2).Result);

            Assert.Throws <KeyNotFoundException>(() =>
            {
                var _ = sa[0];
            });

            Assert.AreEqual(1, sa[1]);
            Assert.AreEqual(2, sa[2]);

            Assert.AreEqual(2, sa.Count());

            for (int i = 3; i < 42000; i++)
            {
                Assert.IsTrue(sa.TryAddLast(i, i).Result);
                Assert.AreEqual(i, sa.Last.Present.Value);
            }

            //// TODO remove when implemented
            //Assert.Throws<NotImplementedException>(() =>
            //{
            //    for (int i = 32000; i < 33000; i++)
            //    {
            //        Assert.IsTrue(sa.TryAddLast(i, i).Result);
            //    }
            //});

            GC.Collect(2, GCCollectionMode.Forced, true, true);
            GC.WaitForPendingFinalizers();
            GC.Collect(2, GCCollectionMode.Forced, true, true);
            GC.WaitForPendingFinalizers();

            sa.Dispose();

            GC.Collect(2, GCCollectionMode.Forced, true, true);
            GC.WaitForPendingFinalizers();
            GC.Collect(2, GCCollectionMode.Forced, true, true);
            GC.WaitForPendingFinalizers();
        }
Пример #2
0
        public void CouldDoubleSeriesCapacity()
        {
            // Debug this test to see buffer management errors during finalization, normal test run survives them in VS

            var block = DataBlock.Create();

            Assert.AreEqual(0, block.RowLength);

            block.IncreaseSeriesCapacity <int, int>();

            Assert.AreEqual(block.RowIndex.Length, Settings.MIN_POOLED_BUFFER_LEN);

            var keys = block.RowIndex._memorySource as ArrayMemory <int>;
            var vals = block.Values._memorySource as ArrayMemory <int>;

            var slice = block.Values.Slice(0, 1);

            Assert.NotNull(keys);
            Assert.NotNull(vals);

            Assert.IsTrue(keys.IsPoolable);
            Assert.IsFalse(keys.IsPooled);

            block.IncreaseSeriesCapacity <int, int>();

            // keys were returned to the pool after doubling capacity
            Assert.IsTrue(keys.IsPooled);

            // values were borrowed via Slice
            Assert.IsFalse(vals.IsPooled);

            slice.Dispose();

            Assert.IsTrue(vals.IsPooled);

            Assert.AreEqual(block.RowIndex.Length, Settings.MIN_POOLED_BUFFER_LEN * 2);

            for (int i = 0; i < 10; i++)
            {
                block.IncreaseSeriesCapacity <int, int>();
                Console.WriteLine(block.RowIndex.Length);
            }

            block.Dispose();
        }
Пример #3
0
        public void CouldTryGetBlockSingleChunkBench()
        {
            var count  = (int)TestUtils.GetBenchCount(50_000_000, 50_000);
            var rounds = TestUtils.GetBenchCount(20, 2);

            // for this test capacity is irrelevant - interpolation search hits exact position on first try
            var capacity = count / 100;
            var bc       = new BaseContainer <long>();

            var rm = BuffersTestHelper.CreateFilledRM(capacity);
            var vs = RetainedVec.Create(rm, 0, rm.Length);

            var block = DataBlock.Create(rowIndex: vs, rowLength: capacity);

            bc.Data = block;

            for (int r = 0; r < rounds; r++)
            {
                using (Benchmark.Run("TryGetBlock", count))
                {
                    var m = count / capacity;
                    for (int _ = 0; _ < m; _++)
                    {
                        for (long i = 0; i < capacity; i++)
                        {
                            var ival  = vs.UnsafeReadUnaligned <long>((IntPtr)i);
                            var ival2 = vs.UnsafeReadUnaligned <long>((IntPtr)capacity - 1);
                            var ival3 = Unsafe.Add <long>(ref vs.UnsafeGetRef <long>(), capacity - 1);
                            var ival4 = Unsafe.Add <long>(ref (bc.Data as DataBlock).RowKeys.UnsafeGetRef <long>(), capacity - 1);
                            var found = bc.TryGetBlock(i, out var c, out var ci);
                            if (!found ||
                                !ReferenceEquals(block, c) ||
                                i != ci
                                )
                            {
                                Assert.Fail();
                            }
                        }
                    }
                }
            }

            Benchmark.Dump();
            bc.Dispose();
        }
Пример #4
0
        public void TestDelegate()
        {
            var blocks = 100_000;
            var length = 1000;
            var count  = length * blocks;

            var db = DataBlock.Create <int, int>(blocks);

            for (int i = 0; i < length; i++)
            {
                Unsafe.As <int[]>(db.Ks)[i] = i;
                Unsafe.As <int[]>(db.Vs)[i] = i;
            }

            for (int r = 0; r < 10; r++)
            {
                db.Getter = null;
                int k = default, v = default;
Пример #5
0
        public void CouldTryFindBlockAtSingleChunkBench()
        {
            var count  = 50_000_000;
            var rounds = 20;

            // for this test capacity is irrelevant - interpolation search hits exact position on first try
            var capacity = count / 100;
            var bc       = new BaseContainer <int>();
            var rm       = ArrayMemory <int> .Create(Enumerable.Range(0, capacity).ToArray());

            var vs = VecStorage.Create(rm, 0, rm.Length);

            var block = DataBlock.Create(rowIndex: vs, rowLength: vs.Vec.Length);

            bc.Data = block;

            for (int r = 0; r < rounds; r++)
            {
                using (Benchmark.Run("TryFindChunkAt", count))
                {
                    var m = count / capacity;
                    for (int _ = 0; _ < m; _++)
                    {
                        for (int i = 1; i < capacity; i++)
                        {
                            var searchIndexRef = i;
                            var found          = bc.TryFindBlockAt(ref searchIndexRef, Lookup.LE, out var c, out var ci);
                            if (!found ||
                                !ReferenceEquals(block, c) ||
                                i != ci ||
                                i != searchIndexRef
                                )
                            {
                                Assert.Fail();
                            }
                        }
                    }
                }
            }

            Benchmark.Dump();
            bc.Dispose();
        }
Пример #6
0
        public void CouldTryFindBlockAtSingleChunkBench()
        {
            var count  = (int)TestUtils.GetBenchCount(50_000_000, 50_000);
            var rounds = TestUtils.GetBenchCount(20, 2);

            // for this test capacity is irrelevant - interpolation search hits exact position on first try
            var capacity = count / 100;
            var bc       = new BaseContainer <long>();
            var rm       = BuffersTestHelper.CreateFilledRM(capacity);
            var vs       = RetainedVec.Create(rm, 0, rm.Length);

            var block = DataBlock.Create(rowIndex: vs, rowLength: capacity);

            bc.Data = block;

            for (int r = 0; r < rounds; r++)
            {
                using (Benchmark.Run("TryFindChunkAt", count))
                {
                    var m = count / capacity;
                    for (int _ = 0; _ < m; _++)
                    {
                        for (long i = 1; i < capacity; i++)
                        {
                            var searchIndexRef = i;
                            var found          = bc.TryFindBlockAt(ref searchIndexRef, Lookup.LE, out var c, out var ci);
                            if (!found ||
                                !ReferenceEquals(block, c) ||
                                i != ci ||
                                i != searchIndexRef
                                )
                            {
                                Assert.Fail();
                            }
                        }
                    }
                }
            }

            Benchmark.Dump();
            bc.Dispose();
        }
Пример #7
0
        private DataBlock GrowCapacity(TKey key, DataBlock block)
        {
            try
            {
                // TODO review: do we want buffers in LOH or not? <= vs <
                // next increment will be 64kb, avoid buffer in LOH
                if (block.RowIndex.Length < MaxBufferLength)
                {
                    if (block.IncreaseSeriesCapacity <TKey, TValue>() < 0)
                    {
                        return(null);
                    }
                }
                else
                {
                    // refactor switching to source logic to reuse in MutableSeries
                    if (DataSource == null)
                    {
                        DataSource = new DataBlockSource <TKey>();
                        DataSource.AddLast(block.RowIndex.DangerousGetRef <TKey>(0), block);
                        DataBlock = null;
                    }

                    var minCapacity = block.RowIndex.Length;
                    var newBlock    = DataBlock.Create();
                    if (newBlock.IncreaseSeriesCapacity <TKey, TValue>(minCapacity) < 0)
                    {
                        return(null);
                    }
                    DataSource.AddLast(key, newBlock);
                    block = newBlock;
                }

                return(block);
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
                return(null);
            }
        }
Пример #8
0
        public void CouldTryGetBlockAtSingleChunk()
        {
            var capacity = 100;
            var bc       = new BaseContainer <int>();

            var rm = BuffersTestHelper.CreateFilledRM(capacity);
            var vs = RetainedVec.Create(rm, 0, rm.Length);

            var block = DataBlock.Create(rowIndex: vs, rowLength: vs.Vec.Length / 2);

            bc.Data = block;

            var searchIndex = 40;
            var found       = bc.TryGetBlockAt(searchIndex, out var dataBlock, out var ci);

            Assert.IsTrue(found);
            Assert.AreSame(block, dataBlock);
            Assert.AreEqual(searchIndex, ci);

            bc.Dispose();
        }
Пример #9
0
        public Series(TKey[] keys, TValue[] values)
        {
            if (keys.Length != values.Length)
            {
                throw new ArgumentException("Different keys and values length");
            }
            var ks = KeySorting.Strong;

            if (keys.Length > 1)
            {
                var cmp = KeyComparer <TKey> .Default;
                for (int i = 1; i < keys.Length; i++)
                {
                    var c = cmp.Compare(keys[i], keys[i - 1]);
                    if (c == 0)
                    {
                        ks = KeySorting.Weak;
                    }
                    else if (c < 0)
                    {
                        ks = KeySorting.NotSorted;
                        break;
                    }
                }
            }
            _flags = new Flags((byte)((byte)Mutability.Immutable | (byte)ks));


            var keyMemory = ArrayMemory <TKey> .Create(keys, externallyOwned : true);

            var keyVs = VectorStorage.Create(keyMemory, 0, keyMemory.Length, 1);

            var valMemory = ArrayMemory <TValue> .Create(values, externallyOwned : true);

            var valVs = VectorStorage.Create(valMemory, 0, valMemory.Length, 1);

            var block = DataBlock.Create(rowIndex: keyVs, values: valVs, rowLength: keys.Length);

            DataBlock = block;
        }
Пример #10
0
        public void CouldTryGetBlockAtSingleChunk()
        {
            var capacity = 100;
            var bc       = new BaseContainer <int>();

            var rm = ArrayMemory <int> .Create(Enumerable.Range(0, capacity).ToArray());

            var vs = VecStorage.Create(rm, 0, rm.Length);

            var block = DataBlock.Create(rowIndex: vs, rowLength: vs.Vec.Length / 2);

            bc.Data = block;

            var searchIndex = 40;
            var found       = bc.TryGetBlockAt(searchIndex, out var dataBlock, out var ci);

            Assert.IsTrue(found);
            Assert.AreSame(block, dataBlock);
            Assert.AreEqual(searchIndex, ci);

            bc.Dispose();
        }
Пример #11
0
        public void CouldTryGetBlockSingleChunk()
        {
            var capacity = 100;
            var bc       = new BaseContainer <long>();
            var rm       = ArrayMemory <long> .Create(Enumerable.Range(0, capacity).Select(x => (long)x).ToArray());

            var vs = VecStorage.Create(rm, 0, rm.Length);

            var block = DataBlock.Create(rowIndex: vs, rowLength: vs.Vec.Length / 2);

            bc.Data = block;

            var searchIndex    = 40L;
            var searchIndexRef = searchIndex;
            var found          = bc.TryGetBlock(searchIndexRef, out var c, out var ci);

            Assert.IsTrue(found);
            Assert.AreSame(block, c);
            Assert.AreEqual(searchIndex, ci);
            Assert.AreEqual(searchIndex, searchIndexRef);
            bc.Dispose();
        }
Пример #12
0
        public void CouldTryFindBlockAtSingleChunk()
        {
            var capacity = 100;
            var bc       = new BaseContainer <long>();

            var rm = BuffersTestHelper.CreateFilledRM(capacity);
            var vs = RetainedVec.Create(rm, 0, rm.Length);

            var block = DataBlock.Create(rowIndex: vs, rowLength: vs.Vec.Length / 2);

            bc.Data = block;

            var searchIndex    = 40L;
            var searchIndexRef = searchIndex;
            var found          = bc.TryFindBlockAt(ref searchIndexRef, Lookup.LT, out var c, out var ci);

            Assert.IsTrue(found);
            Assert.AreSame(block, c);
            Assert.AreEqual(searchIndex - 1, ci);
            Assert.AreEqual(searchIndex - 1, searchIndexRef);

            bc.Dispose();
        }
Пример #13
0
        public void CouldTryFindBlockAtSingleChunk()
        {
            var capacity = 100;
            var bc       = new BaseContainer <long>();

            var rm = ArrayMemory <long> .Create(Enumerable.Range(0, capacity).Select(x => (long)x).ToArray(), externallyOwned : true);

            var vs = VectorStorage.Create(rm, 0, rm.Length, 1);

            var block = DataBlock.Create(rowIndex: vs, rowLength: vs.Length / 2);

            bc.DataBlock = block;

            var searchIndex    = 40L;
            var searchIndexRef = searchIndex;
            var found          = bc.TryFindBlockAt(ref searchIndexRef, Lookup.LT, out var c, out var ci);

            Assert.IsTrue(found);
            Assert.AreSame(block, c);
            Assert.AreEqual(searchIndex - 1, ci);
            Assert.AreEqual(searchIndex - 1, searchIndexRef);

            bc.Dispose();
        }
Пример #14
0
        public void CouldAppendSeriesBench()
        {
            if (AdditionalCorrectnessChecks.Enabled)
            {
                Console.WriteLine("AdditionalCorrectnessChecks.Enabled");
            }

            int count  = 10_000_000;
            int rounds = 100;

            var sa = new AppendSeries <int, int>(DataBlock.Create());
            var sm = new SortedMap <int, int>();

            //for (int r = 0; r < rounds; r++)
            //{
            //    using (Benchmark.Run("SM.TryAddLast", count))
            //    {
            //        for (int i = r * count; i < (r + 1) * count; i++)
            //        {
            //            if (i == r * count + 3)
            //            {
            //                continue;
            //            }
            //            if (!sm.TryAddLast(i, i).Result)
            //            {
            //                Assert.Fail("Cannot add " + i);
            //            }
            //        }
            //    }
            //    Console.WriteLine($"Added {((r + 1) * count / 1000000).ToString("N")}");
            //}

            for (int r = 0; r < rounds; r++)
            {
                using (Benchmark.Run("Append", count))
                {
                    for (int i = r * count; i < (r + 1) * count; i++)
                    {
                        if (i == r * count + 3)
                        {
                            continue;
                        }
                        if (!sa.TryAddLast(i, i).Result)
                        {
                            Console.WriteLine("Cannot add " + i);
                            return;
                        }
                    }
                }

                Console.WriteLine($"Added {((r + 1) * count / 1000000).ToString("N")}");
            }



            Benchmark.Dump();

            Console.WriteLine("Finished, press enter");
            Console.ReadLine();

            sa.Dispose();
        }