コード例 #1
0
        public void Should_outperform_MD5_average_case_performance()
        {
            //going to use a reasonably large string, because it forces additional cleanup work to occur in the tail
            var testBytes   = Encoding.Unicode.GetBytes("*****@*****.**");
            var targetItems = 1000000; //1 million hash attempts
            var i           = targetItems;
            var start       = DateTime.UtcNow.Ticks;

            while (i > 0)
            {
                Murmur3.Hash(testBytes);
                i--;
            }
            var end            = DateTime.UtcNow.Ticks;
            var murmur3Elapsed = new TimeSpan(end - start);

            start = DateTime.UtcNow.Ticks;
            var m5 = MD5.Create();

            i = targetItems;
            while (i > 0)
            {
                m5.ComputeHash(testBytes);
                i--;
            }
            end = DateTime.UtcNow.Ticks;
            var md5Elapsed = new TimeSpan(end - start);

            Assert.IsTrue(murmur3Elapsed.Ticks < md5Elapsed.Ticks, "Expected Murmur3 to be faster than MD5");
            Assert.Pass("Murmur3 completed in {0} seconds; MD5 in {1} seconds", murmur3Elapsed.TotalSeconds, md5Elapsed.TotalSeconds);
        }
コード例 #2
0
        public override Routee Select(object message, Routee[] routees)
        {
            if (message == null)
            {
                return(NoRoutee.NoRoutee);
            }

            if (_hashMapping.ContainsKey(message.GetType()))
            {
                var key = _hashMapping[message.GetType()](message);
                if (key == null)
                {
                    return(NoRoutee.NoRoutee);
                }

                var hash = Murmur3.Hash(key);
                return(routees[Math.Abs(hash) % routees.Length]); //The hash might be negative, so we have to make sure it's positive
            }
            else if (message is ConsistentHashable)
            {
                var hashable = (ConsistentHashable)message;
                int hash     = Murmur3.Hash(hashable.ConsistentHashKey);
                return(routees[Math.Abs(hash) % routees.Length]); //The hash might be negative, so we have to make sure it's positive
            }
            else
            {
                _log.Value.Warn("Message [{0}] must be handled by hashMapping, or implement [{1}] or be wrapped in [{2}]", message.GetType().Name, typeof(ConsistentHashable).Name, typeof(ConsistentHashableEnvelope).Name);
                return(NoRoutee.NoRoutee);
            }
        }
コード例 #3
0
        private static Func <string, Node> CreateNodeFunc(string value)
        {
            var nodeType        = EvaluateNodeType(value);
            var namespaceString = CreateNamespaceString(value);
            var id = Murmur3.Hash(value).ToString();

            return(key => new Node(id, nodeType, namespaceString));
        }
コード例 #4
0
        public void Should_compute_equivalent_hash_value_for_primitives()
        {
            var int1 = 1;
            var int2 = 1;

            var hash1 = Murmur3.Hash(int1);
            var hash2 = Murmur3.Hash(int2);

            Assert.AreEqual(hash1, hash2);
        }
コード例 #5
0
        public void Should_compute_equivalent_hash_value_for_strings()
        {
            var str1 = "this is a string";
            var str2 = "this is a string";

            var hash1 = Murmur3.Hash(str1);
            var hash2 = Murmur3.Hash(str2);

            Assert.AreEqual(hash1, hash2);
        }
コード例 #6
0
        public void Should_NOT_compute_equivalent_hash_value_for_byte_equivalent_primitives()
        {
            var int1  = 1;
            var bool1 = true;

            //bitwise, these two values should be equivalent
            //HOWEVER, Murmur3 takes the byte-array length into account as part of its hash.
            //thus, the values SHOULD NOT BE EQUIVALENT
            var hash1 = Murmur3.Hash(int1);
            var hash2 = Murmur3.Hash(bool1);

            Assert.AreNotEqual(hash1, hash2);
        }
コード例 #7
0
        public void Should_compute_equivalent_hash_values_for_equivalent_POCOs()
        {
            var poco1 = new TestPoco()
            {
                Name = "Aaron", Value = 1337
            };
            var poco2 = new TestPoco()
            {
                Name = "Aaron", Value = 1337
            };

            var hash1 = Murmur3.Hash(poco1);
            var hash2 = Murmur3.Hash(poco2);

            Assert.AreEqual(hash1, hash2);
        }
コード例 #8
0
        public void Should_have_low_number_of_Guid_collisions()
        {
            var targetItems = 1000000; //10 million guids
            var i           = targetItems;
            var start       = DateTime.UtcNow.Ticks;
            var hashes      = new HashSet <int>();

            while (i > 0)
            {
                var hash = Murmur3.Hash(Guid.NewGuid());
                hashes.Add(hash);
                i--;
            }
            var end      = DateTime.UtcNow.Ticks;
            var timespan = new TimeSpan(end - start);
            var epsilon  = (double)(targetItems - hashes.Count) / targetItems;

            Assert.IsTrue(epsilon <= 0.00125d, string.Format("Larger number of hash collisions ({0}%) than acceptable.", epsilon * 100));
            Assert.Pass("Test completed in {0} seconds with {1}% collisions", timespan.TotalSeconds, epsilon * 100);
        }
コード例 #9
0
        public Graph QueryResource(NodeType nodeType, string resource)
        {
            var results = QuerySparql(nodeType, resource);

            var nodeDictionary = new Dictionary <string, Node>();
            var edgeSet        = new HashSet <Edge>();

            foreach (var result in results)
            {
                var subjectValue   = GetResultValue(result, "subject");
                var predicateValue = GetResultValue(result, "predicate");
                var objectValue    = GetResultValue(result, "object");

                var subjectNode = nodeDictionary.ComputeIfAbsent(subjectValue, CreateNodeFunc(subjectValue));
                var objectNode  = nodeDictionary.ComputeIfAbsent(objectValue, CreateNodeFunc(objectValue));

                var toHash = subjectNode.Id + "/" + objectNode.Id;
                var id     = Murmur3.Hash(toHash).ToString();
                edgeSet.Add(new Edge(id, subjectNode.Id, objectNode.Id, CreateNamespaceString(predicateValue)));
            }

            return(new Graph(nodeDictionary.Values, edgeSet));
        }
コード例 #10
0
        /// <summary>
        /// Perform Model Service request
        /// </summary>
        public ModelServiceResponse <T> PerformRequest <T>(IModelServiceRequest request)
        {
            Uri    requestUri   = request.BuildRequestUri(this);
            bool   success      = true;
            uint   hashcode     = 0;
            string responseBody = null;

            try
            {
                responseBody = PerformRequest(requestUri);
                hashcode     = Murmur3.Hash(responseBody);
            }
            catch (ModelServiceRequestException e)
            {
                success      = false;
                responseBody = e.ResponseBody;
            }
            catch
            {
                success = false;
            }

            ModelServiceError serviceError;

            try
            {
                if (success)
                {
                    T responseObject;
                    if (typeof(T) == typeof(string))
                    {
                        responseObject = (T)Convert.ChangeType(responseBody, typeof(T));
                    }
                    else
                    {
                        responseObject = JsonConvert.DeserializeObject <T>(responseBody, JsonSettings(request.Binder));
                    }
                    return(ModelServiceResponse <T> .Create(responseObject, hashcode));
                }
                serviceError = JsonConvert.DeserializeObject <ModelServiceError>(responseBody);
            }
            catch (Exception ex)
            {
                const int maxCharactersToLog = 1000;
                if ((responseBody != null) && (responseBody.Length > maxCharactersToLog))
                {
                    responseBody = responseBody.Substring(0, maxCharactersToLog) + "...";
                }
                throw new ModelServiceException(
                          $"{ModelServiceName} returned an unexpected response from request '{requestUri}' of {responseBody}.", ex);
            }

            if (serviceError == null || serviceError.Status == (int)HttpStatusCode.NotFound)
            {
                throw new ItemNotFoundException(
                          $"{ModelServiceName} failed to locate item from request '{requestUri}'.");
            }

            throw new ModelServiceException(
                      $"{ModelServiceName} returned an error: {serviceError.Message ?? serviceError.Error}");
        }