/// <summary>
        ///
        /// </summary>
        /// <param name="keys"></param>
        /// <param name="hash"></param>
        /// <returns></returns>
        /// <remarks>If any of the keys are null or empty, the method will return false.</remarks>
        public static bool TryCreate(string[] keys, out PerfectHash hash)
        {
            if (keys == null)
            {
                throw new ArgumentNullException(nameof(keys));
            }

            int[] codes = new int[keys.Length];
            for (int i = 0; i < codes.Length; i++)
            {
                var key = keys[i];
                if (string.IsNullOrEmpty(key))
                {
                    hash = default;
                    return(false);
                }
                codes[i] = ComputeCode(key);
            }

            if (AreUnique(codes, out int min, out int max))
            {
                var size = max - min + 1;
                if (size < 256 * 256) // TODO: isn't it too large?
                {
                    hash = new PerfectHash(min, size);
                    return(true);
                }
            }

            hash = default;
            return(false);
        }
 private PerfectHashStore(PerfectHash hash, IReadOnlyDictionary <string, object> properties)
 {
     _hash   = hash;
     _values = new object[_hash.Size];
     foreach (var property in properties)
     {
         var index = _hash.ComputeHash(property.Key);
         _values[index] = property.Value;
     }
 }
        public static PropertyStore Create(IReadOnlyDictionary <string, object> properties)
        {
            var names = new string[properties.Count];
            int i     = 0;

            foreach (var property in properties)
            {
                names[i++] = property.Key;
            }

            if (PerfectHash.TryCreate(names, out var hash))
            {
                return(new PerfectHashStore(hash, properties));
            }

            // TODO: this should log very time a non-perfect store is created
            return(new DictionaryStore(properties));
        }