public void Test_ColaOrderedDictionary_Add()
		{
			var cmp = new CountingComparer<int>();

			var cola = new ColaOrderedDictionary<int, string>(cmp);
			Assert.That(cola.Count, Is.EqualTo(0));

			cola.Add(42, "42");
			cola.Debug_Dump();
			Assert.That(cola.Count, Is.EqualTo(1));
			Assert.That(cola.ContainsKey(42), Is.True);

			cola.Add(1, "1");
			cola.Debug_Dump();
			Assert.That(cola.Count, Is.EqualTo(2));
			Assert.That(cola.ContainsKey(1), Is.True);

			cola.Add(66, "66");
			cola.Debug_Dump();
			Assert.That(cola.Count, Is.EqualTo(3));
			Assert.That(cola.ContainsKey(66), Is.True);

			cola.Add(123, "123");
			cola.Debug_Dump();
			Assert.That(cola.Count, Is.EqualTo(4));
			Assert.That(cola.ContainsKey(123), Is.True);

			for(int i = 1; i < 100; i++)
			{
				cola.Add(-i, (-i).ToString());
			}
			cola.Debug_Dump();


			cmp.Reset();
			cola.ContainsKey(-99);
			Console.WriteLine("Lookup last inserted: " + cmp.Count);

			cmp.Reset();
			cola.ContainsKey(42);
			Console.WriteLine("Lookup first inserted: " + cmp.Count);

			cmp.Reset();
			cola.ContainsKey(77);
			Console.WriteLine("Lookup not found: " + cmp.Count);

			var keys = new List<int>();

			foreach(var kvp in cola)
			{
				Assert.That(kvp.Value, Is.EqualTo(kvp.Key.ToString()));
				keys.Add(kvp.Key);
			}

			Assert.That(keys.Count, Is.EqualTo(cola.Count));
			Assert.That(keys, Is.Ordered);
			Console.WriteLine(String.Join(", ", keys));

		}
		public void Test_Check_Costs()
		{
			const int N = 100;
			var cmp = new CountingComparer<Slice>(Comparer<Slice>.Default);
			var cola = new ColaOrderedSet<Slice>(cmp);

			Console.WriteLine(String.Format(CultureInfo.InvariantCulture, "Parameters: N = {0}, Log(N) = {1}, Log2(N) = {2}, N.Log2(N) = {3}", N, Math.Log(N), Math.Log(N, 2), N * Math.Log(N, 2)));

			Console.WriteLine("Inserting (" + N + " items)");
			for (int i = 0; i < N; i++)
			{
				cola.Add(FdbTuple.EncodeKey(i << 1));
			}

			Console.WriteLine("> " + cmp.Count + " cmps (" + ((double)cmp.Count / N) + " / insert)");
			cola.Debug_Dump();

			Console.WriteLine("Full scan (" + (N << 1) + " lookups)");
			cmp.Reset();
			int n = 0;
			for (int i = 0; i < (N << 1); i++)
			{
				if (cola.Contains(FdbTuple.EncodeKey(i))) ++n;
			}
			Assert.That(n, Is.EqualTo(N));
			Console.WriteLine("> " + cmp.Count + " cmps (" + ((double)cmp.Count / (N << 1)) + " / lookup)");

			cmp.Reset();
			n = 0;
			int tail = Math.Min(16, N >> 1);
			int offset = N - tail;
			Console.WriteLine("Tail scan (" + tail + " lookups)");
			for (int i = 0; i < tail; i++)
			{
				if (cola.Contains(FdbTuple.EncodeKey(offset + i))) ++n;
			}
			Console.WriteLine("> " + cmp.Count + " cmps (" + ((double)cmp.Count / tail) + " / lookup)");

			Console.WriteLine("ForEach");
			cmp.Reset();
			int p = 0;
			foreach(var x in cola)
			{
				Assert.That(FdbTuple.DecodeKey<int>(x), Is.EqualTo(p << 1));
				++p;
			}
			Assert.That(p, Is.EqualTo(N));
			Console.WriteLine("> " + cmp.Count + " cmps (" + ((double)cmp.Count / N) + " / item)");
		}