internal override AbstractBucket Remove(int hash, K key, IEqualityComparer <K> keyComparer) { int logicalSlot = ComputeLogicalSlot(hash); if (IsInUse(logicalSlot)) { int physicalSlot = ComputePhysicalSlot(logicalSlot); var existing = this.buckets[physicalSlot]; AbstractBucket result = existing.Remove(hash, key, keyComparer); if (result == null) { if (this.buckets.Length == 1) { return(null); } else if (this.buckets.Length == 2) { return(physicalSlot == 0 ? this.buckets[1] : this.buckets[0]); } else { return(new HashBucket(this.hashRoll, RemoveBit(logicalSlot, this.used), this.buckets.RemoveAt(physicalSlot), this.count - existing.Count)); } } else if (this.buckets[physicalSlot] != result) { return(new HashBucket(this.hashRoll, this.used, this.buckets.ReplaceAt(physicalSlot, result), this.count - existing.Count + result.Count)); } } return(this); }
private ImmutableDictionary( AbstractBucket rootOpt, IEqualityComparer <K> keyEqualityComparerOpt, IEqualityComparer <V> valueEqualityComparerOpt) { this.rootOpt = rootOpt; this.KeyComparer = keyEqualityComparerOpt ?? EqualityComparer <K> .Default; this.valueEqualityComparer = valueEqualityComparerOpt ?? EqualityComparer <V> .Default; }
private AbstractBucket AddBucket(AbstractBucket root, K key, V value, bool mutate) { var vb = new ValueBucket(key, value, this.KeyComparer); if (root == null) { return(vb); } else { return(root.Add(0, vb, this.KeyComparer, mutate)); } }