public void Set(DotvvmProperty p, object?value) { if (values == null) { var d = new Dictionary <DotvvmProperty, object?>(); d[p] = value; this.values = d; } else if (keys == null) { Debug.Assert(values is Dictionary <DotvvmProperty, object?>); valuesAsDictionary[p] = value; } else { Debug.Assert(this.values is object[]); Debug.Assert(this.keys is DotvvmProperty[]); var keys = this.keysAsArray; var values = this.valuesAsArray; var slot = PropertyImmutableHashtable.FindSlot(keys, this.hashSeed, p); if (slot >= 0 && Object.Equals(values[slot], value)) { // no-op, we would be changing it to the same value } else { var d = new Dictionary <DotvvmProperty, object?>(); for (int i = 0; i < keys.Length; i++) { if (keys[i] != null) { d[keys[i] !] = values[i];
public void AssignBulk(DotvvmProperty[] keys, object[] values, int hashSeed) { // The explicit layout is quite likely to mess with array covariance, just make sure we don't encounter that Debug.Assert(values.GetType() == typeof(object[])); Debug.Assert(keys.GetType() == typeof(DotvvmProperty[])); Debug.Assert(keys.Length == values.Length); if (this.values == null || this.keys == keys) { this.valuesAsArray = values; this.keysAsArray = keys; this.hashSeed = hashSeed; } else { // we can just to check if all current properties are in the proposed set // if they are not we will have to copy it if (this.keys == null) // TODO: is this heuristic actually useful? { var ok = true; foreach (var x in (Dictionary <DotvvmProperty, object>) this.values) { var e = PropertyImmutableHashtable.FindSlot(keys, hashSeed, x.Key); if (e < 0 || !Object.Equals(values[e], x.Value)) { ok = false; } } if (ok) { this.values = values; this.keys = keys; this.hashSeed = hashSeed; return; } } for (int i = 0; i < keys.Length; i++) { if (keys[i] != null) { this.Set(keys[i], values[i]); } } } }
public bool TryGet(DotvvmProperty p, out object value) { value = null; if (values == null) { return(false); } if (keys == null) { Debug.Assert(values is Dictionary <DotvvmProperty, object>); return(valuesAsDictionary.TryGetValue(p, out value)); } Debug.Assert(values is object[]); Debug.Assert(keys is DotvvmProperty[]); var index = PropertyImmutableHashtable.FindSlot(this.keysAsArray, this.hashSeed, p); if (index != -1) { value = this.valuesAsArray[index & (this.keysAsArray.Length - 1)]; } return(index != -1); }