Exemple #1
0
        public void Disk_Read_Write()
        {
            var settings = new EngineSettings
            {
                MemorySegmentSize = 10,
                DataStream        = new MemoryStream(),
                LogStream         = new MemoryStream()
            };

            var disk  = new DiskService(settings);
            var pages = new List <PageBuffer>();

            // let's create 100 pages with 0-99 full data
            for (var i = 0; i < 100; i++)
            {
                var p = disk.NewPage();

                p.Fill((byte)i);  // fills with 0 - 99

                pages.Add(p);
            }

            // page will be saved in LOG file in PagePosition order (0-99)
            disk.WriteAsync(pages);

            // wait for async queue writes
            disk.Queue.Wait();

            // after release, no page can be read/write
            pages.Clear();

            // lets do some read tests
            var reader = disk.GetReader();

            for (var i = 0; i < 100; i++)
            {
                var p = reader.ReadPage(i * 8192, false, FileOrigin.Log);

                p.All((byte)i).Should().BeTrue();

                p.Release();
            }

            // test cache in use
            disk.Cache.PagesInUse.Should().Be(0);

            // wait all async threads
            disk.Dispose();
        }
        public void CacheAsync_Thread_ShareCounter()
        {
            // Set()   - Seta true - Se estiver bloqueado, vai liberar
            // Reset() - Seta false - Quando chegar no proximo Wait() vai aguardar
            // Wait()  - Trava a thread SE estiver false (Reset) - Passa reto se estiver true (Set)
            var wa = new ManualResetEventSlim(true);
            var wb = new ManualResetEventSlim(false);

            // serialize 2 threads
            void serialize(ManualResetEventSlim toBlock, ManualResetEventSlim toFree)
            {
                toBlock?.Reset();
                toFree.Set();
                toBlock?.Wait();
            }

            ;

            var disk = new DiskService(new EngineSettings {
                DataStream = new MemoryStream(), MemorySegmentSize = 10
            });

            var ta = new Task(() =>
            {
                var r = disk.GetReader();
                wa.Wait();

                // test starts here!!!
                var p0 = new HeaderPage(r.NewPage(), 0);

                p0.UserVersion = 25;

                disk.WriteAsync(new PageBuffer[] { p0.UpdateBuffer() });

                // (1 ->) jump to thread B
                serialize(wa, wb);
                // (2 <-) continue from thread B

                disk.Queue.Wait();

                // (3 ->) jump to thread B
                serialize(wa, wb);
            });

            var tb = new Task(() =>
            {
                var r = disk.GetReader();
                wb.Wait();

                // (1 <-) continue from thread A
                var p0 = r.ReadPage(0, false, FileOrigin.Log);

                // share counter can be 2 or 3
                // - if 2, page was not persisted yet on disk (async)
                // - if 1, page already persisted on disk
                var share = p0.ShareCounter;

                (share >= 1 && share <= 2).Should().BeTrue();

                // (2 ->) jump to thread A
                serialize(wb, wa);
                // (3 <-) continue from thread B

                // but now, I'm sure this page was saved and thread A release
                p0.ShareCounter.Should().Be(1);

                // let's release my page
                p0.Release();

                p0.ShareCounter.Should().Be(0);

                // release thread A
                serialize(null, wa);
            });

            ta.Start();
            tb.Start();

            Task.WaitAll(ta, tb);
        }