public void can_remove_values() { var mem = new MemorySimulator(Mega.Bytes(1)); var subject = new TaggedHashMap(64, new Allocator(0, Mega.Bytes(1), mem), mem); subject.Add(50000000, 123); subject.Add(1, 456); var ok1 = subject.Get(1, out _); var ok2 = subject.Get(50000000, out _); var ok3 = subject.Get(50, out _); Assert.That(ok1, Is.True); Assert.That(ok2, Is.True); Assert.That(ok3, Is.False); // remove one value at beginning subject.Remove(1); ok1 = subject.Get(1, out _); ok2 = subject.Get(50000000, out _); ok3 = subject.Get(50, out _); Assert.That(ok1, Is.False); Assert.That(ok2, Is.True); Assert.That(ok3, Is.False); }
public void can_check_for_presence_of_a_key() { var mem = new MemorySimulator(Mega.Bytes(1)); var subject = new TaggedHashMap(64, new Allocator(0, Mega.Bytes(1), mem), mem); subject.Add(123, 0); subject.Add(1, 456); Assert.That(subject.ContainsKey(123), Is.True); Assert.That(subject.ContainsKey(321), Is.False); }
public void deallocating_the_hash_map_releases_memory() { var mem = new MemorySimulator(Mega.Bytes(20)); var alloc = new Allocator(Mega.Bytes(10), Mega.Bytes(20), mem); var subject = new TaggedHashMap(256, alloc, mem); for (ulong i = 0; i < 128; i++) { subject.Add(i, i * 2); } // Check that memory is used... alloc.GetState(out var allocatedBytes, out var unallocatedBytes, out var occupiedArenas, out var emptyArenas, out var totalReferenceCount, out var largestContiguous); Assert.That(allocatedBytes, Is.GreaterThanOrEqualTo(6000), "Allocated bytes looks too small"); //Assert.That(unallocatedBytes, Is.LessThan(Mega.Bytes(10)), "Unallocated bytes looks too big: "+unallocatedBytes); Assert.That(occupiedArenas, Is.EqualTo(1), "Occupied arenas looks wrong"); Assert.That(emptyArenas, Is.GreaterThanOrEqualTo(100), "Empty arenas looks wrong"); Assert.That(totalReferenceCount, Is.GreaterThan(2), "Reference count looks wrong"); Assert.That(largestContiguous, Is.EqualTo(Allocator.ArenaSize), "Should not have exhausted memory!"); // Release the hash map subject.Deallocate(); // Check that everything is released alloc.GetState(out allocatedBytes, out unallocatedBytes, out occupiedArenas, out emptyArenas, out totalReferenceCount, out largestContiguous); Assert.That(allocatedBytes, Is.EqualTo(0), "Memory was not freed"); Assert.That(unallocatedBytes, Is.GreaterThan(Mega.Bytes(9)), "Unallocated bytes not correct"); Assert.That(occupiedArenas, Is.EqualTo(0), "Some arenas still occupied"); Assert.That(emptyArenas, Is.GreaterThanOrEqualTo(100), "Empty arenas looks wrong"); Assert.That(totalReferenceCount, Is.EqualTo(0), "Some references still dangling"); Assert.That(largestContiguous, Is.EqualTo(Allocator.ArenaSize), "Should not have exhausted memory!"); }
public void stress_test() { var rnd = new Random(); // we deliberately use a small initial size to stress the scaling. // if you can afford to oversize the map, that will make things a lot faster var mem = new MemorySimulator(Mega.Bytes(10)); var subject = new TaggedHashMap(100, new Allocator(0, Mega.Bytes(10), mem), mem); subject.Add(0, 1); for (int i = 0; i < /*100000*/ 25_000; i++) // 25'000 should be under a second { if (!subject.Put((ulong)rnd.Next(1, 1_000_000), (ulong)i, true)) { Assert.Fail("Put rejected the change"); } subject.Remove((ulong)rnd.Next(1, 1_000_000)); } Assert.That(subject.Count, Is.GreaterThan(1000)); // there will probably be key collisions var ok = subject.Get(0, out var val); Assert.That(ok, Is.True); Assert.That(val, Is.EqualTo(1)); }
public void can_store_and_retrieve_items() { var mem = new MemorySimulator(Mega.Bytes(1)); var subject = new TaggedHashMap(64, new Allocator(0, Mega.Bytes(1), mem), mem); subject.Add(50000000, 123); subject.Add(1, 456); var ok1 = subject.Get(1, out var val1); var ok2 = subject.Get(50000000, out var val2); var ok3 = subject.Get(50, out _); Assert.That(ok1, Is.True); Assert.That(ok2, Is.True); Assert.That(ok3, Is.False); Assert.That(val1, Is.EqualTo(456)); Assert.That(val2, Is.EqualTo(123)); }
public const int TestSize = 10_000_000; // large enough to keep the program running for a while static void Main(string[] args) { var RamSize = Giga.Bytes(1); var rnd = new Random(); var mem = new MemorySimulator(RamSize); var subject = new TaggedHashMap(TestSize, new Allocator(0, RamSize, mem), mem); Console.WriteLine("running..."); subject.Add(0, 1); for (int i = 0; i < TestSize; i++) // 100'000 should have an acceptable run time. 25'000 should be well under a second { if (!subject.Put((ulong)rnd.Next(1, 1000000), (ulong)i, true)) { throw new Exception("Bad push"); } subject.Remove((ulong)rnd.Next(1, 1000000)); } Console.WriteLine("done"); }
public void a_hashmap_with_contents_can_be_cleared_and_reused() { var mem = new MemorySimulator(Mega.Bytes(1)); var subject = new TaggedHashMap(64, new Allocator(0, Mega.Bytes(1), mem), mem); Assert.That(subject.Count, Is.Zero, "New hash map not empty?"); // first run subject.Add(1, 123); subject.Add(2, 456); subject.Add(3, 456); Assert.That(subject.Count, Is.Not?.Zero, "Failed to write test data"); // wipe out subject.Clear(); Assert.That(subject.Count, Is.Zero, "Hashmap not cleared"); // second run to show it still works subject.Add(4, 123); subject.Add(3, 456); subject.Add(2, 456); Assert.That(subject.Count, Is.Not?.Zero, "Failed to write data after clearing"); }