Exemple #1
0
        public void HeadTests()
        {
            var seq4 = new ShieldedSeq <int>(
                Enumerable.Range(1, 10).ToArray());

            Shield.InTransaction(() => { seq4.Prepend(100); });
            Assert.AreEqual(11, seq4.Count);
            Assert.AreEqual(100, seq4.Head);
            Assert.AreEqual(100, seq4.First());
            Assert.IsTrue(seq4.Any());

            Assert.AreEqual(100,
                            Shield.InTransaction(() => seq4.TakeHead()));
            Assert.AreEqual(10, seq4.Count);
            Assert.AreEqual(1, seq4.Head);
            Assert.IsTrue(seq4.Any());

            for (int i = 0; i < 10; i++)
            {
                Assert.AreEqual(i + 1, seq4.Head);
                Assert.AreEqual(i + 1, Shield.InTransaction(() => seq4.TakeHead()));
            }

            Assert.Throws <InvalidOperationException>(() =>
                                                      Shield.InTransaction(() => {
                seq4.TakeHead();
            }));
            Assert.Throws <InvalidOperationException>(() => {
                var x = seq4.Head;
            });

            Assert.IsFalse(seq4.Any());
            Assert.AreEqual(0, seq4.Count);
        }
Exemple #2
0
        public void InsertTest()
        {
            var emptySeq = new ShieldedSeqNc <int>();

            Shield.InTransaction(() => emptySeq.Insert(0, 1));
            Assert.IsTrue(emptySeq.Any());
            Assert.AreEqual(1, emptySeq[0]);
            Assert.Throws <InvalidOperationException>(() => emptySeq.Count());
            Shield.InTransaction(() =>
                                 Assert.AreEqual(1, emptySeq.Count()));

            var seq = new ShieldedSeq <int>(2, 3, 4, 6, 7);

            Shield.InTransaction(() => seq.Insert(0, 1));
            Assert.AreEqual(6, seq.Count);
            Assert.AreEqual(1, seq[0]);
            Assert.AreEqual(2, seq[1]);

            Shield.InTransaction(() => seq.Insert(4, 5));
            Assert.AreEqual(7, seq.Count);
            Assert.AreEqual(1, seq[0]);
            Assert.AreEqual(2, seq[1]);
            Assert.AreEqual(5, seq[4]);
            Assert.AreEqual(6, seq[5]);

            Shield.InTransaction(() => seq.Insert(7, 8));
            Assert.AreEqual(8, seq.Count);
            Shield.InTransaction(() => {
                for (int i = 0; i < seq.Count; i++)
                {
                    Assert.AreEqual(i + 1, seq[i]);
                }
            });
        }
Exemple #3
0
        public void RemoveAllLastElement()
        {
            var seq = new ShieldedSeq <int>(Enumerable.Range(1, 10).ToArray());

            Shield.InTransaction(() => seq.RemoveAll(i => i == 10));
            Shield.InTransaction(() =>
                                 Assert.IsTrue(seq.SequenceEqual(Enumerable.Range(1, 9))));
        }
Exemple #4
0
        public void TwoQueuesTest()
        {
            var seq1 = new ShieldedSeq <int>();
            var seq2 = new ShieldedSeq <int>();

            // conflict should happen only on the accessed sequence, if we're appending to two..

            int    transactionCount = 0;
            Thread oneTimer         = null;

            Shield.InTransaction(() => {
                transactionCount++;
                seq2.Append(2);
                seq1.Append(1);
                if (oneTimer == null)
                {
                    oneTimer = new Thread(() => Shield.InTransaction(() =>
                    {
                        seq2.Append(1);
                    }));
                    oneTimer.Start();
                    oneTimer.Join();
                }
                var b = seq1.Any();
            });
            Assert.AreEqual(1, transactionCount);
            Assert.AreEqual(2, seq2.Count);
            Assert.IsTrue(seq2.Any());
            Assert.AreEqual(1, seq2[0]);
            Assert.AreEqual(2, seq2[1]);

            Shield.InTransaction(() => { seq1.Clear(); seq2.Clear(); });
            transactionCount = 0;
            oneTimer         = null;
            Shield.InTransaction(() => {
                transactionCount++;
                seq1.Append(1);
                seq2.Append(2);
                if (oneTimer == null)
                {
                    oneTimer = new Thread(() => Shield.InTransaction(() =>
                    {
                        seq2.Append(1);
                    }));
                    oneTimer.Start();
                    oneTimer.Join();
                }
                // the difference is here - seq2:
                var b = seq2.Any();
            });
            Assert.AreEqual(2, transactionCount);
            Assert.AreEqual(2, seq2.Count);
            Assert.IsTrue(seq2.Any());
            Assert.AreEqual(1, seq2[0]);
            Assert.AreEqual(2, seq2[1]);
        }
Exemple #5
0
        public void RemoveAllWithExceptions()
        {
            var seq = new ShieldedSeq <int>(Enumerable.Range(1, 10).ToArray());

            Shield.InTransaction(() =>
                                 // handling the exception here means the transaction will commit.
                                 Assert.Throws <InvalidOperationException>(() => seq.RemoveAll(i => {
                if (i == 5)
                {
                    throw new InvalidOperationException();
                }
                return(true);
            })));
            Assert.AreEqual(5, seq[0]);
            Assert.AreEqual(6, seq.Count);
        }
Exemple #6
0
        public void TailPassTest()
        {
            // pass by the tail - potential commute bug
            // - when you append(), and then iterate a seq,
            //   will you find the new last item missing?
            var tailPass = new ShieldedSeq <int>(
                Enumerable.Range(1, 5).ToArray());

            Shield.InTransaction(() => {
                tailPass.Append(6);
                int counter = 0;
                foreach (var i in tailPass)
                {
                    counter++;
                }
                Assert.AreEqual(6, counter);
            });

            Shield.InTransaction(() => {
                // this causes immediate degeneration of the Append commute.
                var h = tailPass.Any();
                tailPass.Append(7);
                int counter = 0;
                foreach (var i in tailPass)
                {
                    counter++;
                }
                Assert.AreEqual(7, counter);
            });

            Shield.InTransaction(() => {
                tailPass.Append(8);
                tailPass.Append(9);
                Assert.AreEqual(1, tailPass.Head);
                int counter = 0;
                foreach (var i in tailPass)
                {
                    Assert.AreEqual(++counter, i);
                }
                Assert.AreEqual(9, counter);
            });
            Assert.AreEqual(9, tailPass.Count);
        }
Exemple #7
0
        public void RemoveTest()
        {
            var seq = new ShieldedSeq <int>(
                Enumerable.Range(1, 20).ToArray());

            Shield.InTransaction(() =>
                                 Assert.IsTrue(seq.Remove(5)));

            Assert.AreEqual(19, seq.Count);
            Assert.IsTrue(seq.Any());
            Assert.AreEqual(1, seq.Head);

            for (int i = 1; i <= 20; i++)
            {
                if (i == 5)
                {
                    continue;
                }
                else
                {
                    Assert.AreEqual(i, seq[i > 5 ? i - 2 : i - 1]);
                }
            }

            Shield.InTransaction(() =>
                                 Assert.IsTrue(seq.Remove(1)));

            Assert.AreEqual(18, seq.Count);
            Assert.IsTrue(seq.Any());
            Assert.AreEqual(2, seq.Head);

            Shield.InTransaction(() =>
                                 Assert.IsTrue(seq.Remove(20)));
            Shield.InTransaction(() =>
                                 Assert.IsFalse(seq.Remove(30)));

            Assert.AreEqual(17, seq.Count);
            Assert.IsTrue(seq.Any());
            Assert.AreEqual(2, seq.Head);
            Assert.AreEqual(19, seq[16]);
        }
Exemple #8
0
        public void Validation()
        {
            var list1 = new ShieldedSeq <int>(Enumerable.Range(1, 100).ToArray());
            var list2 = new ShieldedSeq <int>();

            int validationFails = 0;

            Shield.PreCommit(() => list1.Count + list2.Count != 100, () => {
                Interlocked.Increment(ref validationFails);
                throw new ValidationException();
            });

            int transactionCount = 0;

            Task.WaitAll(
                Enumerable.Range(1, 100).Select(i => Task.Factory.StartNew(() =>
            {
                try
                {
                    Shield.InTransaction(() =>
                    {
                        Interlocked.Increment(ref transactionCount);
                        int x = list1.TakeHead();
                        if (i < 100)
                        {
                            list2.Append(x);
                        }
                    });
                    Assert.AreNotEqual(100, i);
                }
                catch (ValidationException)
                {
                    Assert.AreEqual(100, i);
                }
            }, TaskCreationOptions.LongRunning)).ToArray());
            Assert.AreEqual(1, validationFails);
            Assert.AreEqual(1, list1.Count);
            Assert.AreEqual(99, list2.Count);
        }
Exemple #9
0
        public void TailPassTest()
        {
            ///////
            // pass by the tail - potential commute bug
            // - when you append(), and then iterate a seq,
            //   will you find the new last item missing?
            var tailPass = new ShieldedSeq<int>(
                Enumerable.Range(1, 5).ToArray());
            Shield.InTransaction(() => {
                tailPass.Append(6);
                int counter = 0;
                foreach (var i in tailPass)
                    counter++;
                Assert.AreEqual(6, counter);
            });

            Shield.InTransaction(() => {
                // this causes immediate degeneration of the Append commute.
                var h = tailPass.HasAny;
                tailPass.Append(7);
                int counter = 0;
                foreach (var i in tailPass)
                    counter++;
                Assert.AreEqual(7, counter);
            });

            Shield.InTransaction(() => {
                tailPass.Append(8);
                tailPass.Append(9);
                Assert.AreEqual(1, tailPass.Head);
                int counter = 0;
                foreach (var i in tailPass)
                    Assert.AreEqual(++counter, i);
                Assert.AreEqual(9, counter);
            });
            Assert.AreEqual(9, tailPass.Count);
        }
Exemple #10
0
        public void RemoveTest()
        {
            var seq = new ShieldedSeq<int>(
                Enumerable.Range(1, 20).ToArray());
            Shield.InTransaction(() => { seq.Remove(5); });

            Assert.AreEqual(19, seq.Count);
            Assert.IsTrue(seq.HasAny);
            Assert.AreEqual(1, seq.Head);

            for (int i = 1; i <= 20; i++)
                if (i == 5)
                    continue;
                else
                    Assert.AreEqual(i, seq[i > 5 ? i - 2 : i - 1]);

            Shield.InTransaction(() => { seq.Remove(1); });

            Assert.AreEqual(18, seq.Count);
            Assert.IsTrue(seq.HasAny);
            Assert.AreEqual(2, seq.Head);

            Shield.InTransaction(() => { seq.Remove(20); });

            Assert.AreEqual(17, seq.Count);
            Assert.IsTrue(seq.HasAny);
            Assert.AreEqual(2, seq.Head);
            Assert.AreEqual(19, seq[16]);
        }
Exemple #11
0
        public void HeadTests()
        {
            var seq4 = new ShieldedSeq<int>(
                Enumerable.Range(1, 10).ToArray());
            Shield.InTransaction(() => { seq4.Prepend(100); });
            Assert.AreEqual(11, seq4.Count);
            Assert.AreEqual(100, seq4.Head);
            Assert.IsTrue(seq4.HasAny);

            Assert.AreEqual(100,
                Shield.InTransaction(() => seq4.TakeHead()));
            Assert.AreEqual(10, seq4.Count);
            Assert.AreEqual(1, seq4.Head);
            Assert.IsTrue(seq4.HasAny);

            for (int i = 0; i < 10; i++)
            {
                Assert.AreEqual(i + 1, seq4.Head);
                Assert.AreEqual(i + 1, Shield.InTransaction(() => seq4.TakeHead()));
            }

            try
            {
                Shield.InTransaction(() => { seq4.TakeHead(); });
                Assert.Fail();
            } catch (InvalidOperationException) { }
            try
            {
                var x = seq4.Head;
                Assert.Fail();
            } catch (InvalidOperationException) { }

            Assert.IsFalse(seq4.HasAny);
            Assert.AreEqual(0, seq4.Count);
        }
Exemple #12
0
        public void ComplexCommute()
        {
            // some more complex commute combinations. first, with ShieldedSeq ops.
            var seq = new ShieldedSeq <int>();

            // just a test for proper commute ordering
            Shield.InTransaction(() => {
                seq.Append(1);
                seq.Append(2);
                seq.Append(3);
                seq.Remove(2);
                Assert.IsTrue(seq.Any());
                Assert.AreEqual(2, seq.Count);
                Assert.AreEqual(1, seq[0]);
                Assert.AreEqual(3, seq[1]);
            });

            // a test for commutability of Append()
            Shield.InTransaction(() => { seq.Clear(); });
            int    transactionCount = 0;
            Thread oneTimer         = null;

            Shield.InTransaction(() => {
                transactionCount++;
                seq.Append(1);
                if (oneTimer == null)
                {
                    oneTimer = new Thread(() => Shield.InTransaction(() =>
                    {
                        seq.Append(2);
                    }));
                    oneTimer.Start();
                    oneTimer.Join();
                }
            });
            Assert.AreEqual(1, transactionCount);
            Assert.AreEqual(2, seq.Count);
            // the "subthread" commited the append first, so:
            Assert.AreEqual(2, seq[0]);
            Assert.AreEqual(1, seq[1]);
            Assert.IsTrue(seq.Any());

            // test for a commute degeneration - reading the head of a list causes
            // appends done in the same transaction to stop being commutable. for
            // simplicity - you could continue from the head on to the tail, and it cannot
            // thus be a commute, you read it. it could, of course, be done that it still
            // is a commute, but that would make it pretty complicated.
            Shield.InTransaction(() => { seq.Clear(); seq.Append(1); seq.Append(2); });
            Assert.AreEqual(1, seq[0]);
            Assert.AreEqual(2, seq[1]);
            transactionCount = 0;
            oneTimer         = null;
            Shield.InTransaction(() => {
                transactionCount++;
                Assert.AreEqual(1, seq.TakeHead());
                seq.Append(4);
                if (oneTimer == null)
                {
                    oneTimer = new Thread(() => Shield.InTransaction(() =>
                    {
                        seq.Append(3);
                    }));
                    oneTimer.Start();
                    oneTimer.Join();
                }
            });
            Assert.AreEqual(2, transactionCount);
            Assert.AreEqual(3, seq.Count);
            Assert.IsTrue(seq.Any());
            Assert.AreEqual(2, seq[0]);
            Assert.AreEqual(3, seq[1]);
            Assert.AreEqual(4, seq[2]);

            Shield.InTransaction(() => { seq.Clear(); seq.Append(1); seq.Append(2); });
            Assert.AreEqual(1, seq[0]);
            Assert.AreEqual(2, seq[1]);
            transactionCount = 0;
            oneTimer         = null;
            Shield.InTransaction(() => {
                // if we switch the order, doesn't matter.
                transactionCount++;
                seq.Append(4);
                Assert.AreEqual(1, seq.TakeHead());
                if (oneTimer == null)
                {
                    oneTimer = new Thread(() => Shield.InTransaction(() =>
                    {
                        seq.Append(3);
                    }));
                    oneTimer.Start();
                    oneTimer.Join();
                }
            });
            Assert.AreEqual(2, transactionCount);
            Assert.AreEqual(3, seq.Count);
            Assert.IsTrue(seq.Any());
            Assert.AreEqual(2, seq[0]);
            Assert.AreEqual(3, seq[1]);
            Assert.AreEqual(4, seq[2]);

            // here the removal takes out the last element in the list. this absolutely cannot
            // commute, because it read from the only element's Next field, and the Seq
            // knew that it was the last element. it must conflict.
            Shield.InTransaction(() => { seq.Clear(); seq.Append(1); });
            Assert.AreEqual(1, seq[0]);
            transactionCount = 0;
            oneTimer         = null;
            Shield.InTransaction(() => {
                transactionCount++;
                Assert.AreEqual(1, seq.TakeHead());
                seq.Append(3);
                if (oneTimer == null)
                {
                    oneTimer = new Thread(() => Shield.InTransaction(() =>
                    {
                        seq.Append(2);
                    }));
                    oneTimer.Start();
                    oneTimer.Join();
                }
            });
            Assert.AreEqual(2, transactionCount);
            Assert.AreEqual(2, seq.Count);
            Assert.IsTrue(seq.Any());
            Assert.AreEqual(2, seq[0]);
            Assert.AreEqual(3, seq[1]);


            // it is not allowed to read another Shielded from a Shielded.Commute()!
            // this greatly simplifies things. if you still want to use a value from another
            // Shielded, you must read it in main trans, forcing it's commutes to degenerate.

            var a = new Shielded <int>();
            var b = new Shielded <int>();

            Assert.Throws <InvalidOperationException>(() =>
                                                      Shield.InTransaction(() => {
                a.Commute((ref int n) => n = 1);
                b.Commute((ref int n) => n = a);
            }));

            Assert.Throws <InvalidOperationException>(() =>
                                                      Shield.InTransaction(() => {
                a.Commute((ref int n) => n = 1);
                b.Commute((ref int n) => {
                    n = 1;
                    a.Commute((ref int n2) => n2 = 2);
                });
            }));

            Shield.InTransaction(() => {
                a.Commute((ref int n) => n = 1);
                b.Commute((ref int n) => n = a);
                Assert.Throws <InvalidOperationException>(() => {
                    var x = b.Value;
                });
            });
        }
Exemple #13
0
        public void ComplexCommute()
        {
            // some more complex commute combinations. first, with ShieldedSeq ops.
            var seq = new ShieldedSeq<int>();

            Shield.InTransaction(() => {
                // test for potential disorder of the seq commutes.
                seq.Append(1);
                seq.Clear();
                Assert.IsFalse(seq.HasAny);
                Assert.AreEqual(0, seq.Count);
            });

            Shield.InTransaction(() => {
                seq.Append(1);
                seq.Append(2);
                seq.Append(3);
                seq.Remove(2);
                Assert.IsTrue(seq.HasAny);
                Assert.AreEqual(2, seq.Count);
                Assert.AreEqual(1, seq[0]);
                Assert.AreEqual(3, seq[1]);
                seq.Clear();
                Assert.IsFalse(seq.HasAny);
                Assert.AreEqual(0, seq.Count);
            });

            Shield.InTransaction(() => { seq.Append(1); seq.Append(2); });
            Assert.AreEqual(1, seq[0]);
            Assert.AreEqual(2, seq[1]);
            int transactionCount = 0;
            Thread oneTimer = null;
            Shield.InTransaction(() => {
                // here's a weird one - the seq is only partially commuted, due to reading
                // from the head, but it still commutes with a trans that is only appending.
                transactionCount++;
                Assert.AreEqual(1, seq.TakeHead());
                // Count or tail were not read! Clearing can commute with appending.
                seq.Clear();
                if (oneTimer == null)
                {
                    oneTimer = new Thread(() => Shield.InTransaction(() =>
                    {
                        seq.Append(3);
                    }));
                    oneTimer.Start();
                    oneTimer.Join();
                }
            });
            Assert.AreEqual(1, transactionCount);
            Assert.AreEqual(0, seq.Count);
            Assert.IsFalse(seq.HasAny);

            Shield.InTransaction(() => { seq.Append(1); seq.Append(2); });
            Assert.AreEqual(1, seq[0]);
            Assert.AreEqual(2, seq[1]);
            transactionCount = 0;
            oneTimer = null;
            Shield.InTransaction(() => {
                // same as above, but with appending, does not work. reading the _head screws it up,
                // because you could continue from the head to the last item.
                transactionCount++;
                Assert.AreEqual(1, seq.TakeHead());
                seq.Append(4);
                if (oneTimer == null)
                {
                    oneTimer = new Thread(() => Shield.InTransaction(() =>
                    {
                        seq.Append(3);
                    }));
                    oneTimer.Start();
                    oneTimer.Join();
                }
            });
            Assert.AreEqual(2, transactionCount);
            Assert.AreEqual(3, seq.Count);
            Assert.IsTrue(seq.HasAny);
            Assert.AreEqual(2, seq[0]);
            Assert.AreEqual(3, seq[1]);
            Assert.AreEqual(4, seq[2]);

            Shield.InTransaction(() => { seq.Clear(); seq.Append(1); seq.Append(2); });
            Assert.AreEqual(1, seq[0]);
            Assert.AreEqual(2, seq[1]);
            transactionCount = 0;
            oneTimer = null;
            Shield.InTransaction(() => {
                // if we switch the order, doesn't matter.
                transactionCount++;
                seq.Append(4);
                Assert.AreEqual(1, seq.TakeHead());
                if (oneTimer == null)
                {
                    oneTimer = new Thread(() => Shield.InTransaction(() =>
                    {
                        seq.Append(3);
                    }));
                    oneTimer.Start();
                    oneTimer.Join();
                }
            });
            Assert.AreEqual(2, transactionCount);
            Assert.AreEqual(3, seq.Count);
            Assert.IsTrue(seq.HasAny);
            Assert.AreEqual(2, seq[0]);
            Assert.AreEqual(3, seq[1]);
            Assert.AreEqual(4, seq[2]);

            Shield.InTransaction(() => { seq.Clear(); seq.Append(1); });
            Assert.AreEqual(1, seq[0]);
            transactionCount = 0;
            oneTimer = null;
            Shield.InTransaction(() => {
                // here the removal takes out the last element in the list. this cannot
                // commute, because it read from the only element's Next field, and the Seq
                // knew that it was the last element. it must conflict.
                transactionCount++;
                Assert.AreEqual(1, seq.TakeHead());
                seq.Append(3);
                if (oneTimer == null)
                {
                    oneTimer = new Thread(() => Shield.InTransaction(() =>
                    {
                        seq.Append(2);
                    }));
                    oneTimer.Start();
                    oneTimer.Join();
                }
            });
            Assert.AreEqual(2, transactionCount);
            Assert.AreEqual(2, seq.Count);
            Assert.IsTrue(seq.HasAny);
            Assert.AreEqual(2, seq[0]);
            Assert.AreEqual(3, seq[1]);

            // it is not allowed to read another Shielded from a Shielded.Commute()!
            // this greatly simplifies things. if you still want to use a value from another
            // Shielded, you must read it in main trans, forcing it's commutes to degenerate.

            var a = new Shielded<int>();
            var b = new Shielded<int>();
            try
            {
                Shield.InTransaction(() => {
                    a.Commute((ref int n) => n = 1);
                    b.Commute((ref int n) => n = a);
                });
                Assert.Fail();
            }
            catch (InvalidOperationException) {}

            try
            {
                Shield.InTransaction(() => {
                    a.Commute((ref int n) => n = 1);
                    b.Commute((ref int n) => { n = 1; a.Commute((ref int n2) => n2 = 2); });
                });
                Assert.Fail();
            }
            catch (InvalidOperationException) {}

            Shield.InTransaction(() => {
                a.Commute((ref int n) => n = 1);
                b.Commute((ref int n) => n = a);
                try
                {
                    var x = b.Read;
                    Assert.Fail();
                }
                catch (InvalidOperationException) {}
            });
        }
Exemple #14
0
 public void RemoveAllLastElement()
 {
     var seq = new ShieldedSeq<int>(Enumerable.Range(1, 10).ToArray());
     Shield.InTransaction(() => seq.RemoveAll(i => i == 10));
     Shield.InTransaction(() =>
         Assert.IsTrue(seq.SequenceEqual(Enumerable.Range(1, 9))));
 }
Exemple #15
0
 public void RemoveAllWithExceptions()
 {
     var seq = new ShieldedSeq<int>(Enumerable.Range(1, 10).ToArray());
     Shield.InTransaction(() =>
         // handling the exception here means the transaction will commit.
         Assert.Throws<InvalidOperationException>(() => seq.RemoveAll(i => {
             if (i == 5)
                 throw new InvalidOperationException();
             return true;
         })));
     Assert.AreEqual(5, seq[0]);
     Assert.AreEqual(6, seq.Count);
 }
        public void Validation()
        {
            var list1 = new ShieldedSeq<int>(Enumerable.Range(1, 100).ToArray());
            var list2 = new ShieldedSeq<int>();

            int validationFails = 0;
            Shield.PreCommit(() => list1.Count + list2.Count != 100, () => {
                Interlocked.Increment(ref validationFails);
                throw new ValidationException();
            });

            int transactionCount = 0;
            Task.WaitAll(
                Enumerable.Range(1, 100).Select(i => Task.Factory.StartNew(() =>
                {
                    try
                    {
                        Shield.InTransaction(() =>
                        {
                            Interlocked.Increment(ref transactionCount);
                            int x = list1.TakeHead();
                            if (i < 100)
                                list2.Append(x);
                        });
                        Assert.AreNotEqual(100, i);
                    }
                    catch (ValidationException)
                    {
                        Assert.AreEqual(100, i);
                    }
                }, TaskCreationOptions.LongRunning)).ToArray());
            Assert.AreEqual(1, validationFails);
            Assert.AreEqual(1, list1.Count);
            Assert.AreEqual(99, list2.Count);
        }
Exemple #17
0
        public void InsertTest()
        {
            var emptySeq = new ShieldedSeqNc<int>();

            Shield.InTransaction(() => emptySeq.Insert(0, 1));
            Assert.IsTrue(emptySeq.Any());
            Assert.AreEqual(1, emptySeq[0]);
            Assert.Throws<InvalidOperationException>(() => emptySeq.Count());
            Shield.InTransaction(() =>
                Assert.AreEqual(1, emptySeq.Count()));

            var seq = new ShieldedSeq<int>(2, 3, 4, 6, 7);

            Shield.InTransaction(() => seq.Insert(0, 1));
            Assert.AreEqual(6, seq.Count);
            Assert.AreEqual(1, seq[0]);
            Assert.AreEqual(2, seq[1]);

            Shield.InTransaction(() => seq.Insert(4, 5));
            Assert.AreEqual(7, seq.Count);
            Assert.AreEqual(1, seq[0]);
            Assert.AreEqual(2, seq[1]);
            Assert.AreEqual(5, seq[4]);
            Assert.AreEqual(6, seq[5]);

            Shield.InTransaction(() => seq.Insert(7, 8));
            Assert.AreEqual(8, seq.Count);
            Shield.InTransaction(() => {
                for (int i=0; i < seq.Count; i++)
                    Assert.AreEqual(i + 1, seq[i]);
            });
        }
Exemple #18
0
        public void BasicOps()
        {
            var seq = new ShieldedSeq<int>(
                Enumerable.Range(1, 20).ToArray());

            Assert.AreEqual(20, seq.Count);
            Assert.IsTrue(seq.HasAny);
            Assert.AreEqual(1, seq.Head);

            for (int i = 0; i < 20; i++)
                Assert.AreEqual(i + 1, seq [i]);

            Shield.InTransaction(() => {
                int i = 1;
                foreach (int x in seq)
                {
                    Assert.AreEqual(i, x);
                    i++;
                }
            });

            ParallelEnumerable.Range(0, 20)
                .ForAll(n => Shield.InTransaction(
                    () => seq [n] = seq [n] + 20)
            );
            for (int i = 0; i < 20; i++)
                Assert.AreEqual(i + 21, seq [i]);

            Shield.InTransaction(() => {
                seq.Append(0);
                // test commute
                Assert.AreEqual(0, seq [20]);
            }
            );
            Assert.AreEqual(21, seq.Count);

            var a = Shield.InTransaction(() => seq.TakeHead());
            Assert.AreEqual(20, seq.Count);
            Assert.AreEqual(21, a);
            for (int i = 0; i < 19; i++)
                Assert.AreEqual(i + 22, seq [i]);
            Assert.AreEqual(0, seq [19]);

            Shield.InTransaction(() => {
                seq.Prepend(a);
                seq.RemoveAt(20);
            }
            );
            Assert.AreEqual(20, seq.Count);
            for (int i = 0; i < 20; i++)
                Assert.AreEqual(i + 21, seq [i]);

            Shield.InTransaction(() => seq.RemoveAll(i => (i & 1) == 1));
            Assert.AreEqual(10, seq.Count);
            for (int i = 0; i < 10; i++)
                Assert.AreEqual(i * 2 + 22, seq [i]);

            var seq2 = new ShieldedSeq<int>(
                Shield.InTransaction(() => seq.ToArray()));
            Shield.InTransaction(() => seq.RemoveAll(i => true));
            Assert.AreEqual(0, seq.Count);
            Shield.InTransaction(() => seq2.Clear());
            Assert.AreEqual(0, seq2.Count);

            var seq3 = new ShieldedSeq<int>(
                Enumerable.Range(1, 5).ToArray());
            Shield.InTransaction(() => seq3.RemoveAt(0));
            Assert.AreEqual(4, seq3.Count);
            Assert.AreEqual(2, seq3 [0]);
            Shield.InTransaction(() => seq3.RemoveAt(3));
            Assert.AreEqual(3, seq3.Count);
            Assert.AreEqual(4, seq3 [2]);
            Shield.InTransaction(() => seq3.Append(100));
            Assert.AreEqual(4, seq3.Count);
            Assert.AreEqual(100, seq3 [3]);
            Shield.InTransaction(() => seq3.RemoveAll(i => i == 100));
            Assert.AreEqual(3, seq3.Count);
            Assert.AreEqual(4, seq3 [2]);
            Shield.InTransaction(() => seq3.Append(100));
            Assert.AreEqual(4, seq3.Count);
            Assert.AreEqual(100, seq3 [3]);
        }
Exemple #19
0
        public void BasicOps()
        {
            var seq = new ShieldedSeq <int>(
                Enumerable.Range(1, 20).ToArray());

            Assert.AreEqual(20, seq.Count);
            Assert.IsTrue(seq.Any());
            Assert.AreEqual(1, seq.Head);

            for (int i = 0; i < 20; i++)
            {
                Assert.AreEqual(i + 1, seq [i]);
            }

            Shield.InTransaction(() => {
                int i = 1;
                foreach (int x in seq)
                {
                    Assert.AreEqual(i, x);
                    i++;
                }
            });

            ParallelEnumerable.Range(0, 20)
            .ForAll(n => Shield.InTransaction(() =>
                                              seq [n] = seq [n] + 20)
                    );
            for (int i = 0; i < 20; i++)
            {
                Assert.AreEqual(i + 21, seq [i]);
            }

            Shield.InTransaction(() => {
                seq.Append(0);
                // test commute
                Assert.AreEqual(0, seq [20]);
            }
                                 );
            Assert.AreEqual(21, seq.Count);

            var a = Shield.InTransaction(() => seq.TakeHead());

            Assert.AreEqual(20, seq.Count);
            Assert.AreEqual(21, a);
            for (int i = 0; i < 19; i++)
            {
                Assert.AreEqual(i + 22, seq [i]);
            }
            Assert.AreEqual(0, seq [19]);

            Shield.InTransaction(() => {
                seq.Prepend(a);
                seq.RemoveAt(20);
            }
                                 );
            Assert.AreEqual(20, seq.Count);
            for (int i = 0; i < 20; i++)
            {
                Assert.AreEqual(i + 21, seq [i]);
            }

            Shield.InTransaction(() => seq.RemoveAll(i => (i & 1) == 1));
            Assert.AreEqual(10, seq.Count);
            for (int i = 0; i < 10; i++)
            {
                Assert.AreEqual(i * 2 + 22, seq [i]);
            }

            var seq2 = new ShieldedSeq <int>(
                Shield.InTransaction(() => seq.ToArray()));

            Shield.InTransaction(() => seq.RemoveAll(i => true));
            Assert.AreEqual(0, seq.Count);
            Shield.InTransaction(() => seq2.Clear());
            Assert.AreEqual(0, seq2.Count);

            var seq3 = new ShieldedSeq <int>(
                Enumerable.Range(1, 5).ToArray());

            Shield.InTransaction(() => seq3.RemoveAt(0));
            Assert.AreEqual(4, seq3.Count);
            Assert.AreEqual(2, seq3 [0]);
            Shield.InTransaction(() => seq3.RemoveAt(3));
            Assert.AreEqual(3, seq3.Count);
            Assert.AreEqual(4, seq3 [2]);
            Shield.InTransaction(() => seq3.Append(100));
            Assert.AreEqual(4, seq3.Count);
            Assert.AreEqual(100, seq3 [3]);
            Shield.InTransaction(() => seq3.RemoveAll(i => i == 100));
            Assert.AreEqual(3, seq3.Count);
            Assert.AreEqual(4, seq3 [2]);
            Shield.InTransaction(() => seq3.Append(100));
            Assert.AreEqual(4, seq3.Count);
            Assert.AreEqual(100, seq3 [3]);
        }
Exemple #20
0
        public void ComplexCommute()
        {
            // some more complex commute combinations. first, with ShieldedSeq ops.
            var seq = new ShieldedSeq<int>();

            // just a test for proper commute ordering
            Shield.InTransaction(() => {
                seq.Append(1);
                seq.Append(2);
                seq.Append(3);
                seq.Remove(2);
                Assert.IsTrue(seq.Any());
                Assert.AreEqual(2, seq.Count);
                Assert.AreEqual(1, seq[0]);
                Assert.AreEqual(3, seq[1]);
            });

            // a test for commutability of Append()
            Shield.InTransaction(() => { seq.Clear(); });
            int transactionCount = 0;
            Thread oneTimer = null;
            Shield.InTransaction(() => {
                transactionCount++;
                seq.Append(1);
                if (oneTimer == null)
                {
                    oneTimer = new Thread(() => Shield.InTransaction(() =>
                        {
                            seq.Append(2);
                        }));
                    oneTimer.Start();
                    oneTimer.Join();
                }
            });
            Assert.AreEqual(1, transactionCount);
            Assert.AreEqual(2, seq.Count);
            // the "subthread" commited the append first, so:
            Assert.AreEqual(2, seq[0]);
            Assert.AreEqual(1, seq[1]);
            Assert.IsTrue(seq.Any());

            // test for a commute degeneration - reading the head of a list causes
            // appends done in the same transaction to stop being commutable. for
            // simplicity - you could continue from the head on to the tail, and it cannot
            // thus be a commute, you read it. it could, of course, be done that it still
            // is a commute, but that would make it pretty complicated.
            Shield.InTransaction(() => { seq.Clear(); seq.Append(1); seq.Append(2); });
            Assert.AreEqual(1, seq[0]);
            Assert.AreEqual(2, seq[1]);
            transactionCount = 0;
            oneTimer = null;
            Shield.InTransaction(() => {
                transactionCount++;
                Assert.AreEqual(1, seq.TakeHead());
                seq.Append(4);
                if (oneTimer == null)
                {
                    oneTimer = new Thread(() => Shield.InTransaction(() =>
                        {
                            seq.Append(3);
                        }));
                    oneTimer.Start();
                    oneTimer.Join();
                }
            });
            Assert.AreEqual(2, transactionCount);
            Assert.AreEqual(3, seq.Count);
            Assert.IsTrue(seq.Any());
            Assert.AreEqual(2, seq[0]);
            Assert.AreEqual(3, seq[1]);
            Assert.AreEqual(4, seq[2]);

            Shield.InTransaction(() => { seq.Clear(); seq.Append(1); seq.Append(2); });
            Assert.AreEqual(1, seq[0]);
            Assert.AreEqual(2, seq[1]);
            transactionCount = 0;
            oneTimer = null;
            Shield.InTransaction(() => {
                // if we switch the order, doesn't matter.
                transactionCount++;
                seq.Append(4);
                Assert.AreEqual(1, seq.TakeHead());
                if (oneTimer == null)
                {
                    oneTimer = new Thread(() => Shield.InTransaction(() =>
                        {
                            seq.Append(3);
                        }));
                    oneTimer.Start();
                    oneTimer.Join();
                }
            });
            Assert.AreEqual(2, transactionCount);
            Assert.AreEqual(3, seq.Count);
            Assert.IsTrue(seq.Any());
            Assert.AreEqual(2, seq[0]);
            Assert.AreEqual(3, seq[1]);
            Assert.AreEqual(4, seq[2]);

            // here the removal takes out the last element in the list. this absolutely cannot
            // commute, because it read from the only element's Next field, and the Seq
            // knew that it was the last element. it must conflict.
            Shield.InTransaction(() => { seq.Clear(); seq.Append(1); });
            Assert.AreEqual(1, seq[0]);
            transactionCount = 0;
            oneTimer = null;
            Shield.InTransaction(() => {
                transactionCount++;
                Assert.AreEqual(1, seq.TakeHead());
                seq.Append(3);
                if (oneTimer == null)
                {
                    oneTimer = new Thread(() => Shield.InTransaction(() =>
                        {
                            seq.Append(2);
                        }));
                    oneTimer.Start();
                    oneTimer.Join();
                }
            });
            Assert.AreEqual(2, transactionCount);
            Assert.AreEqual(2, seq.Count);
            Assert.IsTrue(seq.Any());
            Assert.AreEqual(2, seq[0]);
            Assert.AreEqual(3, seq[1]);

            // it is not allowed to read another Shielded from a Shielded.Commute()!
            // this greatly simplifies things. if you still want to use a value from another
            // Shielded, you must read it in main trans, forcing it's commutes to degenerate.

            var a = new Shielded<int>();
            var b = new Shielded<int>();
            Assert.Throws<InvalidOperationException>(() =>
                Shield.InTransaction(() => {
                    a.Commute((ref int n) => n = 1);
                    b.Commute((ref int n) => n = a);
                }));

            Assert.Throws<InvalidOperationException>(() =>
                Shield.InTransaction(() => {
                    a.Commute((ref int n) => n = 1);
                    b.Commute((ref int n) => {
                        n = 1;
                        a.Commute((ref int n2) => n2 = 2);
                    });
                }));

            Shield.InTransaction(() => {
                a.Commute((ref int n) => n = 1);
                b.Commute((ref int n) => n = a);
                Assert.Throws<InvalidOperationException>(() => {
                    var x = b.Value;
                });
            });
        }
Exemple #21
0
        public void TwoQueuesTest()
        {
            var seq1 = new ShieldedSeq<int>();
            var seq2 = new ShieldedSeq<int>();

            // conflict should happen only on the accessed sequence, if we're appending to two..

            int transactionCount = 0;
            Thread oneTimer = null;
            Shield.InTransaction(() => {
                transactionCount++;
                seq2.Append(2);
                seq1.Append(1);
                if (oneTimer == null)
                {
                    oneTimer = new Thread(() => Shield.InTransaction(() =>
                    {
                        seq2.Append(1);
                    }));
                    oneTimer.Start();
                    oneTimer.Join();
                }
                var b = seq1.HasAny;
            });
            Assert.AreEqual(1, transactionCount);
            Assert.AreEqual(2, seq2.Count);
            Assert.IsTrue(seq2.HasAny);
            Assert.AreEqual(1, seq2[0]);
            Assert.AreEqual(2, seq2[1]);

            Shield.InTransaction(() => { seq1.Clear(); seq2.Clear(); });
            transactionCount = 0;
            oneTimer = null;
            Shield.InTransaction(() => {
                transactionCount++;
                seq1.Append(1);
                seq2.Append(2);
                if (oneTimer == null)
                {
                    oneTimer = new Thread(() => Shield.InTransaction(() =>
                    {
                        seq2.Append(1);
                    }));
                    oneTimer.Start();
                    oneTimer.Join();
                }
                var b = seq2.HasAny;
            });
            Assert.AreEqual(2, transactionCount);
            Assert.AreEqual(2, seq2.Count);
            Assert.IsTrue(seq2.HasAny);
            Assert.AreEqual(1, seq2[0]);
            Assert.AreEqual(2, seq2[1]);
        }
Exemple #22
0
        public void HeadTests()
        {
            var seq4 = new ShieldedSeq<int>(
                Enumerable.Range(1, 10).ToArray());
            Shield.InTransaction(() => { seq4.Prepend(100); });
            Assert.AreEqual(11, seq4.Count);
            Assert.AreEqual(100, seq4.Head);
            Assert.AreEqual(100, seq4.First());
            Assert.IsTrue(seq4.Any());

            Assert.AreEqual(100,
                Shield.InTransaction(() => seq4.TakeHead()));
            Assert.AreEqual(10, seq4.Count);
            Assert.AreEqual(1, seq4.Head);
            Assert.IsTrue(seq4.Any());

            for (int i = 0; i < 10; i++)
            {
                Assert.AreEqual(i + 1, seq4.Head);
                Assert.AreEqual(i + 1, Shield.InTransaction(() => seq4.TakeHead()));
            }

            Assert.Throws<InvalidOperationException>(() =>
                Shield.InTransaction(() => {
                    seq4.TakeHead();
                }));
            Assert.Throws<InvalidOperationException>(() => {
                var x = seq4.Head;
            });

            Assert.IsFalse(seq4.Any());
            Assert.AreEqual(0, seq4.Count);
        }