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];
Exemple #2
0
        public bool Contains(DotvvmProperty p)
        {
            if (values == null)
            {
                return(false);
            }

            if (keys == null)
            {
                Debug.Assert(values is Dictionary <DotvvmProperty, object>);
                return(valuesAsDictionary.ContainsKey(p));
            }

            Debug.Assert(values is object[]);
            Debug.Assert(keys is DotvvmProperty[]);
            return(PropertyImmutableHashtable.ContainsKey(this.keysAsArray, this.hashSeed, p));
        }
Exemple #3
0
        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]);
                    }
                }
            }
        }
Exemple #4
0
        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);
        }