public static void ConcurrentInsert(ConcurrentRBTree <long, Data> rbTree, int numOfThreads,
                                            long nodesPerThread, HashSet <long> keys)
        {
            var values = keys.Select(i => new Tuple <long, Data>(i, new Data {
                Value = i.ToString()
            })).ToArray();

            var threads = new Thread[numOfThreads];

            for (var i = 0; i < threads.Length; i++)
            {
                var iLocal = i;
                threads[i] = new Thread(() =>
                {
                    var start = iLocal * nodesPerThread;
                    var end   = start + nodesPerThread - 1;
                    for (var j = start; j <= end; j++)
                    {
                        rbTree.Add(values[j].Item1, values[j].Item2);
                    }
                });
            }

            // starting inserts
            var watch = new Stopwatch();

            watch.Start();

            foreach (var thread in threads)
            {
                thread.Start();
            }

            foreach (var thread in threads)
            {
                thread.Join();
            }

            watch.Stop();

            Console.WriteLine($"Node count after insertion: {(rbTree.Count())}");
            Console.WriteLine($"Tree depth: {rbTree.MaxDepth()}");
            Console.WriteLine();
            Console.WriteLine();
        }
Beispiel #2
0
        public static void ConcurrentInsertTest(ConcurrentRBTree <long, Data> rbTree, int numOfThreads,
                                                long nodesPerThread, long totalNodesToInsert, long nodesMaxKeyValue)
        {
            var rand = new Random();

            var key = 1 + (long)(rand.NextDouble() * nodesMaxKeyValue);

            rbTree.Add(key, new Data {
                Value = key.ToString()
            });

            var keys = new HashSet <long>();

            for (var i = 0; i < totalNodesToInsert; i++)
            {
                long value;
                while (true)
                {
                    value = 1 + (long)(rand.NextDouble() * nodesMaxKeyValue);
                    if (!keys.Contains(value) && value != key)
                    {
                        break;
                    }
                }
                keys.Add(value);
            }

            var values = keys.Select(i => new Tuple <long, Data>(i, new Data {
                Value = i.ToString()
            })).ToArray();

            var threads = new Thread[numOfThreads];

            for (var i = 0; i < threads.Length; i++)
            {
                var iLocal = i;
                threads[i] = new Thread(() =>
                {
                    var start = iLocal * nodesPerThread;
                    var end   = start + nodesPerThread - 1;
                    for (var j = start; j <= end; j++)
                    {
                        rbTree.Add(values[j].Item1, values[j].Item2);
                    }
                });
            }

            Console.WriteLine("************* Insertion Test ***************");
            Console.WriteLine();

            Console.WriteLine($"Total nodes to insert: {totalNodesToInsert}");
            Console.WriteLine($"Total threads: {numOfThreads}");
            Console.WriteLine($"Total nodes per thread: {nodesPerThread}");
            Console.WriteLine();

            // starting inserts
            var watch = new Stopwatch();

            watch.Start();

            foreach (var thread in threads)
            {
                thread.Start();
            }

            foreach (var thread in threads)
            {
                thread.Join();
            }

            watch.Stop();

            Console.WriteLine($"Total time spent in insertion: {watch.ElapsedMilliseconds} ms");
            Console.WriteLine();

            Console.WriteLine($"Node count after insertion: {rbTree.Count()}");
            Console.WriteLine();

            Console.WriteLine($"Tree depth: {rbTree.MaxDepth()}");
            Console.WriteLine();
            Console.WriteLine();
        }
        public static void ConcurrentInsertDeleteTest(ConcurrentRBTree <long, Data> rbTree, long totalNodesInTree, int numOfThreads,
                                                      int nodesPerThread, long totalNodesToDelete, long totalNodesToInsert, long nodesMaxKeyValue)
        {
            Console.WriteLine("************* Create Tree ***************");
            Console.WriteLine();

            ConcurrentInsertTest(rbTree, 12, totalNodesInTree / 12, totalNodesInTree, nodesMaxKeyValue, false);

            Console.WriteLine($"Node count of tree: {(rbTree.Count())}");
            Console.WriteLine();

            Console.WriteLine($"Tree depth: {rbTree.MaxDepth()}");
            Console.WriteLine();
            Console.WriteLine();


            // generate valid deletable items
            var deleteCount = 0;
            var deleteItems = new HashSet <long>();
            var rand        = new Random();

            while (true)
            {
                long target;
                while (true)
                {
                    target = 1 + (long)(rand.NextDouble() * nodesMaxKeyValue);
                    if (!deleteItems.Contains(target))
                    {
                        break;
                    }
                }
                var data = rbTree.GetData(target);

                if (data != null)
                {
                    deleteItems.Add(data.Item1);
                    deleteCount++;
                }

                if (deleteCount == totalNodesToDelete)
                {
                    break;
                }
            }
            var keysToDelete = deleteItems.ToArray();

            var deleteThreads = new Thread[numOfThreads];

            for (var i = 0; i < deleteThreads.Length; i++)
            {
                var iLocal = i;
                deleteThreads[i] = new Thread(() =>
                {
                    var start = iLocal * nodesPerThread;
                    var end   = start + nodesPerThread - 1;
                    for (var j = start; j <= end; j++)
                    {
                        rbTree.Remove(keysToDelete[j]);
                    }
                });
                deleteThreads[i].Name = i.ToString();
            }

            // generate valid insertable items
            var insertCount = 0;
            var insertItems = new HashSet <long>();

            while (true)
            {
                long target;
                while (true)
                {
                    target = 1 + (long)(rand.NextDouble() * nodesMaxKeyValue);
                    if (!insertItems.Contains(target))
                    {
                        break;
                    }
                }
                var data = rbTree.GetData(target);

                if (data == null)
                {
                    insertItems.Add(target);
                    insertCount++;
                }

                if (insertCount == totalNodesToInsert)
                {
                    break;
                }
            }
            var values = insertItems.Select(i => new Tuple <long, Data>(i, new Data {
                Value = i.ToString()
            })).ToArray();

            var insertThreads = new Thread[numOfThreads];

            for (var i = 0; i < insertThreads.Length; i++)
            {
                var iLocal = i;
                insertThreads[i] = new Thread(() =>
                {
                    var start = iLocal * nodesPerThread;
                    var end   = start + nodesPerThread - 1;
                    for (var j = start; j <= end; j++)
                    {
                        rbTree.Add(values[j].Item1, values[j].Item2);
                    }
                });
                insertThreads[i].Name = i.ToString();
            }

            Console.WriteLine("************* Insert-Delete Test ***************");
            Console.WriteLine();

            Console.WriteLine($"Total nodes to insert: {totalNodesToInsert}");
            Console.WriteLine($"Total nodes to delete: {totalNodesToDelete}");
            Console.WriteLine($"Total threads: {numOfThreads}");
            Console.WriteLine($"Total nodes per thread: {nodesPerThread}");
            Console.WriteLine();

            // starting inserts
            var watch = new Stopwatch();

            watch.Start();

            for (var i = 0; i < numOfThreads; i++)
            {
                insertThreads[i].Start();
                deleteThreads[i].Start();
            }

            for (var i = 0; i < numOfThreads; i++)
            {
                insertThreads[i].Join();
                deleteThreads[i].Join();
            }

            watch.Stop();

            Console.WriteLine($"Total time spent in simultaneous insertion & deletion: {watch.ElapsedMilliseconds} ms");
            Console.WriteLine();

            Console.WriteLine($"Node count after insertion: {(rbTree.Count())}");
            Console.WriteLine();

            Console.WriteLine($"Tree depth: {rbTree.MaxDepth()}");
            Console.WriteLine();
            Console.WriteLine();
        }