示例#1
0
        public void TestThreadSafety(int cnt, int tcount, int seconds)
        {
            using (var pile = new DefaultPile())
            {
                // pile.SegmentSize = 64 * 1024 * 1024;
                pile.Start();

                var data = new PilePointer[cnt];
                for (var i = 0; i < cnt; i++)
                {
                    data[i] = pile.Put(new byte[0], preallocateBlockSize: Memory.PTR_RAW_BYTE_SIZE + (137 * (i % 17)));
                }

                var lst = new List <Task>();

                long statRead   = 0;
                long statPut    = 0;
                long statDelete = 0;

                var sw         = Stopwatch.StartNew();
                var sd         = DateTime.UtcNow;
                var deleteLock = new object();
                for (var i = 0; i < tcount; i++)
                {
                    lst.Add(Task.Factory.StartNew(() =>
                    {
                        while (true)
                        {
                            var now = DateTime.UtcNow;
                            if ((now - sd).TotalSeconds > seconds)
                            {
                                break;
                            }

                            var it = ExternalRandomGenerator.Instance.NextScaledRandomInteger(10, 100);
                            for (var j = 0; j < it; j++)
                            {
                                var pp = data[ExternalRandomGenerator.Instance.NextScaledRandomInteger(0, cnt - 1)];
                                Aver.IsTrue(pile.Get(pp) is byte[]);
                                Interlocked.Increment(ref statRead);
                            }

                            it = ExternalRandomGenerator.Instance.NextScaledRandomInteger(10, 100);
                            for (var j = 0; j < it; j++)
                            {
                                var pp = data[ExternalRandomGenerator.Instance.NextScaledRandomInteger(0, cnt - 1)];
                                Aver.IsTrue(pile.Put(pp, new byte[ExternalRandomGenerator.Instance.NextScaledRandomInteger(0, 3791)], link: true));
                                Interlocked.Increment(ref statPut);
                            }

                            if (ExternalRandomGenerator.Instance.NextScaledRandomInteger(0, 100) > 50 && Monitor.TryEnter(deleteLock))
                            {
                                try
                                {
                                    var newData  = (PilePointer[])data.Clone();
                                    it           = ExternalRandomGenerator.Instance.NextScaledRandomInteger(0, 10 + (cnt / 2));
                                    var toDelete = new List <PilePointer>();
                                    for (var j = 0; j < it; j++)
                                    {
                                        var idx = ExternalRandomGenerator.Instance.NextScaledRandomInteger(0, cnt - 1);
                                        toDelete.Add(newData[idx]);
                                        newData[idx] = pile.Put(new byte[12], preallocateBlockSize: ExternalRandomGenerator.Instance.NextScaledRandomInteger(24, 1024));
                                    }
                                    data = newData;//atomic;
                                    Thread.Sleep(1000);
                                    foreach (var pp in toDelete)
                                    {
                                        Aver.IsTrue(pile.Delete(pp));
                                        Interlocked.Increment(ref statDelete);
                                    }
                                }
                                finally
                                {
                                    Monitor.Exit(deleteLock);
                                }
                            }
                        }
                    }, TaskCreationOptions.LongRunning));
                }

                Task.WaitAll(lst.ToArray());

                var el = sw.ElapsedMilliseconds;

                Console.WriteLine("Read {0:n0} at {1:n0} ops/sec".Args(statRead, statRead / (el / 1000d)));
                Console.WriteLine("Put {0:n0} at {1:n0} ops/sec".Args(statPut, statPut / (el / 1000d)));
                Console.WriteLine("Deleted {0:n0} at {1:n0} ops/sec".Args(statDelete, statDelete / (el / 1000d)));

                for (var i = 0; i < data.Length; i++)
                {
                    Aver.IsTrue(pile.Delete(data[i]));
                }


                Aver.AreEqual(0, pile.ObjectCount);
                Aver.AreEqual(0, pile.ObjectLinkCount);
                Aver.AreEqual(0, pile.AllocatedMemoryBytes);
            }
        }