public void HopscotchMap()
        {
            var map = new HopscotchMap <int, int>(8, 10000);
            var bag = new ConcurrentBag <int>();
            var completitionSources = new TaskCompletionSource <bool> [8];
            int initialID           = new Random().Next(1000000);

            for (int i = 0; i < completitionSources.Length; i++)
            {
                int j = i;
                completitionSources[j] = new TaskCompletionSource <bool>();
                new Thread(() =>
                {
                    ComplexTest(map, MapCapacity, bag, j + initialID);
                    completitionSources[j].SetResult(true);
                }).Start();
            }
            Task[] tasks = completitionSources.Select(t => t.Task).ToArray();
            Task.WaitAll(tasks);
            var errors = tasks.Where(t => t.IsFaulted).Select(t => t.Exception).ToArray();

            if (errors.Length > 0)
            {
                throw new AggregateException(errors);
            }
        }
示例#2
0
 private HopscotchMap(HopscotchMap <TKey, TValue> original)
 {
     keyComparer  = original.keyComparer;
     segmentShift = original.segmentShift;
     segmentMask  = original.segmentMask;
     bucketMask   = original.bucketMask;
     segments     = new Segment[original.segments.Length];
     for (int i = 0; i < segments.Length; i++)
     {
         segments[i]           = new Segment();
         segments[i].timestamp = original.segments[i].timestamp;
     }
     table = (Bucket[])original.table.Clone();
 }
        static void ComplexTest(HopscotchMap <int, int> map, int capacity, ConcurrentBag <int> bag, int id)
        {
            var random = new Random(id);
            var clone  = map;

            for (int i = 0; i < capacity * 1000; i++)
            {
                if (random.Next(100) < 40 || bag.Count > capacity * 2 / 3)
                {
                    int element;
                    if (bag.TryTake(out element))
                    {
                        int data;
                        if (!map.Remove(element, out data))
                        {
                            throw new InvalidOperationException("Cannot remove element");
                        }
                        if (data != element)
                        {
                            throw new InvalidOperationException("Data doesn't match key");
                        }
                    }
                }
                else
                {
                    int key    = random.Next(capacity * 3);
                    var result = map.PutIfAbsent(key, key);

                    if (result == PutResult.Success)
                    {
                        if (!map.ContainsKey(key))
                        {
                            throw new InvalidOperationException("no key after insert");
                        }
                        bag.Add(key);
                    }
                }
            }
        }