Exemplo n.º 1
0
        public void CouldAddNextChunkBeforeCompleted()
        {
            var path          = TestUtils.GetPath();
            var processConfig = new ProcessConfig(path);

            StartupConfig.StreamLogBufferPoolFlags = LMDBEnvironmentFlags.NoSync;
            StartupConfig.StreamBlockIndexFlags    = LMDBEnvironmentFlags.NoSync;
            var slm = new StreamLogManager(processConfig, "CouldAddNextChunk", null, 512, true, true);

            var bufferPool = slm.BufferPool;

            var blockIndex = slm.BlockIndex;

            var streamId = (StreamLogId)42;

            short valueSize = 8;

            var state = slm.StateStorage.GetState(streamId);

            state.CheckInit(streamId, 8, SerializationFormat.Binary);

            var sl = new StreamLog(slm, state, textId: "test_stream");

            var count = 100;

            SharedMemory currentBuffer = null;

            using (Benchmark.Run("AddNext (KOPS)", count * 1000))
            {
                var version = 1UL;
                var block   = blockIndex.RentNextWritableBlock(sl, minimumLength: 1, version, default);
                // var slc = new StreamBlock(buffer.RetainChunkMemory(false), streamId, valueSize, 1);

                var firstBufferRef = block.SharedMemory.BufferRef;

                for (int i = 0; i < count; i++)
                {
                    version = (ulong)i + 1;

                    if (!block.Claim(version, 8).IsValid)
                    {
                        Assert.Fail("!slc.Claim(version, 8).IsValid");
                    }
                    block.Commit();

                    var bufferRef = block.SharedMemory.BufferRef;

                    blockIndex.PrepareNextWritableStreamBlock(sl, length: 1);
                    blockIndex.PrepareNextWritableStreamBlock(sl, length: 1);
                    block.Complete();

                    block = blockIndex.RentNextWritableBlock(sl, minimumLength: 1, version + 1, default);
                    var bufferRef1 = block.SharedMemory.BufferRef;
                    // As if someone has created the next buffer before the second call, forget the first call

                    block.DisposeFree();
                    block = blockIndex.RentNextWritableBlock(sl, minimumLength: 1, version + 1, default);
                    var bufferRef2 = block.SharedMemory.BufferRef;

                    if (block.SharedMemory.ReferenceCount != 2)
                    {
                        Assert.Fail($"buffer.RefCount {block.SharedMemory.ReferenceCount} != 1");
                    }

                    if (bufferRef1 != bufferRef2)
                    {
                        Assert.Fail($"bufferRef1 {bufferRef1} != bufferRef2 {bufferRef2}");
                    }

                    block.Complete();

                    var nextVersion = block.NextVersion;
                    block.DisposeFree();

                    blockIndex.PrepareNextWritableStreamBlock(sl, length: 1);
                    blockIndex.PrepareNextWritableStreamBlock(sl, length: 1);

                    // block = new StreamBlock(block.SharedMemory.RetainBlockMemory(false), streamId, valueSize, nextVersion);
                    block = blockIndex.RentNextWritableBlock(sl, minimumLength: 1, nextVersion, default);
                }

                if (!block.Claim(version + 1, 8).IsValid)
                {
                    Assert.Fail("!slc.Claim(version, 8).IsValid");
                }
                block.Commit();
                block.Complete();

                block = blockIndex.RentNextWritableBlock(sl, minimumLength: 1, block.NextVersion, default);

                Assert.AreEqual(2, block.SharedMemory.ReferenceCount);

                block.DisposeFree();
                block = blockIndex.RentNextWritableBlock(sl, minimumLength: 1, version + 2, default);

                Assert.IsFalse(block.IsCompleted);

                // TODO test replace

                //// replace existing
                //var toReplaceVersion = slc.FirstVersion;
                //var toReplaceRef = buffer.BufferRef;

                //slc.Complete();
                //// SharedMemory.Free(buffer);
                //// slc.DisposeFree();

                //buffer = chunkIndex.GetOrCreateNextWritableChunkBuffer(sl, toReplaceVersion, toReplaceRef, 1);
                //slc = new StreamLogChunk(buffer.RetainChunkMemory(false), streamId, valueSize, version + 2);
                //Assert.AreNotEqual(toReplaceRef, buffer.BufferRef);

                // SharedMemory.Free(buffer);
                block.DisposeFree();
            }

            //bufferPool.PrintBuffers();

            //bufferPool.PrintBuffersAfterPoolDispose = true;

            Benchmark.Dump();
            Console.WriteLine("Finished");
            sl.Dispose();
            slm.Dispose();
        }