Exemplo n.º 1
0
        public void RemoveTest()
        {
            var dict = new ShieldedDict <string, object>(new KeyValuePair <string, object>[] {
                new KeyValuePair <string, object>("key a", null),
                new KeyValuePair <string, object>("key b", null),
                new KeyValuePair <string, object>("key c", null),
            });

            Assert.Throws <InvalidOperationException>(() =>
                                                      dict.Remove("key a"));
            Assert.Throws <InvalidOperationException>(() =>
                                                      ((ICollection <KeyValuePair <string, object> >)dict).Remove(
                                                          new KeyValuePair <string, object>("key a", null)));

            Shield.InTransaction(() => {
                dict.Remove("key a");
                Assert.AreEqual(2, dict.Count);
                Assert.IsFalse(dict.ContainsKey("key a"));
            });
            Assert.AreEqual(2, dict.Count);
            Assert.IsFalse(dict.ContainsKey("key a"));

            Shield.InTransaction(() => {
                ((ICollection <KeyValuePair <string, object> >)dict).Remove(
                    new KeyValuePair <string, object>("key b", null));
                Assert.AreEqual(1, dict.Count);
                Assert.IsFalse(dict.ContainsKey("key b"));
            });
            Assert.AreEqual(1, dict.Count);
            Assert.IsFalse(dict.ContainsKey("key b"));
            // ToList() avoids the need for a transaction, usually needed for enumerating collections.
            Assert.AreEqual("key c", dict.ToList().Single().Key);
        }
Exemplo n.º 2
0
        public void ContainsTest()
        {
            var dict = new ShieldedDict <string, object>(new KeyValuePair <string, object>[] {
                new KeyValuePair <string, object>("key a", null),
                new KeyValuePair <string, object>("key b", null),
                new KeyValuePair <string, object>("key c", null),
            });

            Assert.IsTrue(dict.ContainsKey("key a"));
            Assert.IsTrue(((ICollection <KeyValuePair <string, object> >)dict).Contains(
                              new KeyValuePair <string, object>("key a", null)));
            Assert.IsFalse(dict.ContainsKey("not me"));
            Assert.IsFalse(((ICollection <KeyValuePair <string, object> >)dict).Contains(
                               new KeyValuePair <string, object>("not me", null)));

            Shield.InTransaction(() => {
                dict.Add("new key", null);
                dict.Remove("key a");
                Assert.IsFalse(dict.ContainsKey("key a"));
                Assert.IsFalse(((ICollection <KeyValuePair <string, object> >)dict).Contains(
                                   new KeyValuePair <string, object>("key a", null)));
                Assert.IsTrue(dict.ContainsKey("new key"));
                Assert.IsTrue(((ICollection <KeyValuePair <string, object> >)dict).Contains(
                                  new KeyValuePair <string, object>("new key", null)));
            });
        }
Exemplo n.º 3
0
        public void EnumerationTest()
        {
            var ordinaryDict = new Dictionary <int, object>()
            {
                { 1, new object() },
                { 101, new object() },
                { 666999, new object() }
            };
            var dict = new ShieldedDict <int, object>(ordinaryDict);

            var addedObject = new object();

            // in preparation for the same changes done to dict inside transaction
            ordinaryDict.Add(2, addedObject);
            ordinaryDict.Remove(666999);

            Shield.InTransaction(() => {
                // as an IShielded implementor, the Dict is more complex and needs to be more carefully
                // tested for how well he manages thread-local data. So, we add some changes here.
                dict.Add(2, addedObject);
                dict.Remove(666999);

                int count    = 0;
                var checkSet = new HashSet <int>();
                foreach (var kvp in dict)
                {
                    Assert.IsTrue(checkSet.Add(kvp.Key));
                    Assert.IsTrue(ordinaryDict.ContainsKey(kvp.Key));
                    Assert.AreEqual(ordinaryDict[kvp.Key], kvp.Value);
                    count++;
                }
                Assert.AreEqual(3, count);
            });
        }
Exemplo n.º 4
0
        public void EnumerationTest()
        {
            var ordinaryDict = new Dictionary <int, object>()
            {
                { 1, new object() },
                { 101, new object() },
                { 666999, new object() }
            };
            var dict = new ShieldedDict <int, object>(ordinaryDict);

            var addedObject = new object();

            // in preparation for the same changes done to dict inside transaction
            ordinaryDict.Add(2, addedObject);
            ordinaryDict.Remove(666999);

            Shield.InTransaction(() => {
                // as an IShielded implementor, the Dict is more complex and needs to be more carefully
                // tested for how well he manages thread-local data. So, we add some changes here.
                dict.Add(2, addedObject);
                dict.Remove(666999);
                Assert.IsTrue(dict.OrderBy(kvp => kvp.Key).SequenceEqual(ordinaryDict.OrderBy(kvp => kvp.Key)));
            });
        }
Exemplo n.º 5
0
 private static void DictionaryTest()
 {
     ShieldedDict<int, Shielded<int>> dict = new ShieldedDict<int, Shielded<int>>();
     var randomizr = new Random();
     foreach (var _ in Enumerable.Repeat(0, 10))
     {
         var transactionCounter = 0;
         var time = mtTest("dictionary", 10000, i =>
         {
             var rnd = randomizr.Next(10);
             if (i % 2 == 0)
                 // adder task - 500 of these
                 return Task.Factory.StartNew(() =>
                 {
                     Shield.InTransaction(() =>
                     {
                         Interlocked.Increment(ref transactionCounter);
                         var v = dict.ContainsKey(rnd) ? dict[rnd] : null;
                         int? num = v != null ? (int?)v.Read : null;
                         Thread.Sleep(1);
                         if (v == null)
                             dict[rnd] = new Shielded<int>(1);
                         else if (v.Read == -1)
                             dict.Remove(rnd);
                         else
                             v.Modify((ref int a) => a = num.Value + 1);
                     }
                     );
                 },
                 TaskCreationOptions.LongRunning
                 );
             else
                 // subtractor task - 500 of these
                 return Task.Factory.StartNew(() =>
                 {
                     Shield.InTransaction(() =>
                     {
                         Interlocked.Increment(ref transactionCounter);
                         var v = dict.ContainsKey(rnd) ? dict[rnd] : null;
                         int? num = v != null ? (int?)v.Read : null;
                         Thread.Sleep(1);
                         if (v == null)
                             dict[rnd] = new Shielded<int>(-1);
                         else if (v.Read == 1)
                             dict.Remove(rnd);
                         else
                             v.Modify((ref int a) => a = num.Value - 1);
                     }
                     );
                 },
                 TaskCreationOptions.LongRunning
                 );
         });
         var sum = Enumerable.Range(0, 10).Sum(n => dict.ContainsKey(n) ? dict[n] : 0);
         Console.WriteLine(" {0} ms with {1} iterations and sum {2}.",
             time, transactionCounter, sum);
     }
 }
Exemplo n.º 6
0
        public void RemoveTest()
        {
            var dict = new ShieldedDict<string, object>(new KeyValuePair<string, object>[] {
                new KeyValuePair<string, object>("key a", null),
                new KeyValuePair<string, object>("key b", null),
                new KeyValuePair<string, object>("key c", null),
            });

            Assert.Throws<InvalidOperationException>(() =>
                dict.Remove("key a"));
            Assert.Throws<InvalidOperationException>(() =>
                ((ICollection<KeyValuePair<string, object>>)dict).Remove(
                    new KeyValuePair<string, object>("key a", null)));

            Shield.InTransaction(() => {
                dict.Remove("key a");
                Assert.AreEqual(2, dict.Count);
                Assert.IsFalse(dict.ContainsKey("key a"));
            });
            Assert.AreEqual(2, dict.Count);
            Assert.IsFalse(dict.ContainsKey("key a"));

            Shield.InTransaction(() => {
                ((ICollection<KeyValuePair<string, object>>)dict).Remove(
                    new KeyValuePair<string, object>("key b", null));
                Assert.AreEqual(1, dict.Count);
                Assert.IsFalse(dict.ContainsKey("key b"));
            });
            Assert.AreEqual(1, dict.Count);
            Assert.IsFalse(dict.ContainsKey("key b"));
            // ToList() avoids the need for a transaction, usually needed for enumerating collections.
            Assert.AreEqual("key c", dict.ToList().Single().Key);
        }
Exemplo n.º 7
0
        public void EnumerationTest()
        {
            var ordinaryDict = new Dictionary<int, object>() {
                { 1, new object() },
                { 101, new object() },
                { 666999, new object() }
            };
            var dict = new ShieldedDict<int, object>(ordinaryDict);

            var addedObject = new object();
            // in preparation for the same changes done to dict inside transaction
            ordinaryDict.Add(2, addedObject);
            ordinaryDict.Remove(666999);

            Shield.InTransaction(() => {
                // as an IShielded implementor, the Dict is more complex and needs to be more carefully
                // tested for how well he manages thread-local data. So, we add some changes here.
                dict.Add(2, addedObject);
                dict.Remove(666999);

                int count = 0;
                var checkSet = new HashSet<int>();
                foreach (var kvp in dict)
                {
                    Assert.IsTrue(checkSet.Add(kvp.Key));
                    Assert.IsTrue(ordinaryDict.ContainsKey(kvp.Key));
                    Assert.AreEqual(ordinaryDict[kvp.Key], kvp.Value);
                    count++;
                }
                Assert.AreEqual(3, count);
            });
        }
Exemplo n.º 8
0
        public void ContainsTest()
        {
            var dict = new ShieldedDict<string, object>(new KeyValuePair<string, object>[] {
                new KeyValuePair<string, object>("key a", null),
                new KeyValuePair<string, object>("key b", null),
                new KeyValuePair<string, object>("key c", null),
            });

            Assert.IsTrue(dict.ContainsKey("key a"));
            Assert.IsTrue(((ICollection<KeyValuePair<string, object>>)dict).Contains(
                new KeyValuePair<string, object>("key a", null)));
            Assert.IsFalse(dict.ContainsKey("not me"));
            Assert.IsFalse(((ICollection<KeyValuePair<string, object>>)dict).Contains(
                new KeyValuePair<string, object>("not me", null)));

            Shield.InTransaction(() => {
                dict.Add("new key", null);
                dict.Remove("key a");
                Assert.IsFalse(dict.ContainsKey("key a"));
                Assert.IsFalse(((ICollection<KeyValuePair<string, object>>)dict).Contains(
                    new KeyValuePair<string, object>("key a", null)));
                Assert.IsTrue(dict.ContainsKey("new key"));
                Assert.IsTrue(((ICollection<KeyValuePair<string, object>>)dict).Contains(
                    new KeyValuePair<string, object>("new key", null)));
            });
        }
Exemplo n.º 9
0
        public void DictionaryAccessExpandingTest()
        {
            var d = new ShieldedDict<int, object>();

            // various combinations - one key is either written or just read, and the
            // WhenCommitting sub tries to mess with another key, or to promote the
            // read key.

            Shield.InTransaction(() => {
                d[1] = new object();
                d[2] = new object();
            });

            // WhenCommitting does not fire unless at least something changed, so we need this
            Shielded<int> x = new Shielded<int>();

            // reader promotion to writer not allowed
            using (Shield.WhenCommitting(fs => d[2] = new object()))
            {
                Assert.Throws<InvalidOperationException>(() =>
                    Shield.InTransaction(() => {
                        x.Value = 1;
                        var obj = d[2];
                    }));
            }
            // new read not allowed
            using (Shield.WhenCommitting(fs => { var obj = d[2]; }))
            {
                Assert.Throws<InvalidOperationException>(() =>
                    Shield.InTransaction(() => {
                        x.Value = 1;
                        var obj = d[1];
                    }));
            }
            // new write not allowed
            using (Shield.WhenCommitting(fs => d[2] = new object()))
            {
                Assert.Throws<InvalidOperationException>(() =>
                    Shield.InTransaction(() => {
                        x.Value = 1;
                        var obj = d[1];
                    }));
            }
            // same checks, but in situations when we did a write in the dict
            using (Shield.WhenCommitting(fs => d[2] = new object()))
            {
                Assert.Throws<InvalidOperationException>(() =>
                    Shield.InTransaction(() => {
                        d[1] = new object();
                        var obj = d[2];
                    }));
            }
            using (Shield.WhenCommitting(fs => { var obj = d[2]; }))
            {
                Assert.Throws<InvalidOperationException>(() =>
                    Shield.InTransaction(() => {
                        d[1] = new object();
                    }));
            }
            using (Shield.WhenCommitting(fs => d[2] = new object()))
            {
                Assert.Throws<InvalidOperationException>(() =>
                    Shield.InTransaction(() => {
                        d[1] = new object();
                    }));
            }

            // removing should likewise be restricted
            using (Shield.WhenCommitting(fs =>
                {
                    d.Remove(1);
                    Assert.Throws<InvalidOperationException>(
                        () => d.Remove(2));
                }))
            {
                Shield.InTransaction(() => {
                    d[1] = new object();
                });
            }
            // the exception was caught, and the WhenCommiting delegate committed
            Assert.IsFalse(d.ContainsKey(1));
            Shield.InTransaction(() => d[1] = new object());

            // finally, something allowed - reading from read or written, and writing into written
            using (Shield.WhenCommitting(fs =>
                {
                    var obj = d[1];
                    var obj2 = d[2];
                    d[2] = new object();
                }))
            {
                Shield.InTransaction(() => {
                    var obj = d[1];
                    d[2] = new object();
                });
            }
        }
Exemplo n.º 10
0
        public void DictionaryAccessExpandingTest()
        {
            var d = new ShieldedDict <int, object>();

            // various combinations - one key is either written or just read, and the
            // WhenCommitting sub tries to mess with another key, or to promote the
            // read key.

            Shield.InTransaction(() => {
                d[1] = new object();
                d[2] = new object();
            });

            // WhenCommitting does not fire unless at least something changed, so we need this
            Shielded <int> x = new Shielded <int>();

            // reader promotion to writer not allowed
            using (Shield.WhenCommitting(fs => d[2] = new object()))
            {
                Assert.Throws <AggregateException>(() =>
                                                   Shield.InTransaction(() => {
                    x.Value = 1;
                    var obj = d[2];
                }));
            }
            // new read not allowed
            using (Shield.WhenCommitting(fs => { var obj = d[2]; }))
            {
                Assert.Throws <AggregateException>(() =>
                                                   Shield.InTransaction(() => {
                    x.Value = 1;
                    var obj = d[1];
                }));
            }
            // new write not allowed
            using (Shield.WhenCommitting(fs => d[2] = new object()))
            {
                Assert.Throws <AggregateException>(() =>
                                                   Shield.InTransaction(() => {
                    x.Value = 1;
                    var obj = d[1];
                }));
            }
            // same checks, but in situations when we did a write in the dict
            using (Shield.WhenCommitting(fs => d[2] = new object()))
            {
                Assert.Throws <AggregateException>(() =>
                                                   Shield.InTransaction(() => {
                    d[1]    = new object();
                    var obj = d[2];
                }));
            }
            using (Shield.WhenCommitting(fs => { var obj = d[2]; }))
            {
                Assert.Throws <AggregateException>(() =>
                                                   Shield.InTransaction(() => {
                    d[1] = new object();
                }));
            }
            using (Shield.WhenCommitting(fs => d[2] = new object()))
            {
                Assert.Throws <AggregateException>(() =>
                                                   Shield.InTransaction(() => {
                    d[1] = new object();
                }));
            }

            // removing should likewise be restricted
            using (Shield.WhenCommitting(fs =>
            {
                d.Remove(1);
                Assert.Throws <InvalidOperationException>(
                    () => d.Remove(2));
            }))
            {
                Shield.InTransaction(() => {
                    d[1] = new object();
                });
            }
            // the exception was caught, and the WhenCommiting delegate committed
            Assert.IsFalse(d.ContainsKey(1));
            Shield.InTransaction(() => d[1] = new object());

            // finally, something allowed - reading from read or written, and writing into written
            using (Shield.WhenCommitting(fs =>
            {
                var obj = d[1];
                var obj2 = d[2];
                d[2] = new object();
            }))
            {
                Shield.InTransaction(() => {
                    var obj = d[1];
                    d[2]    = new object();
                });
            }
        }