• 一般性hash算法c#版


    hash算法实现代码如下:

    继承自c#的HashAlgorithm类

    View Code
       public class FNV1a : HashAlgorithm
        {
            private const uint Prime = 16777619;
            private const uint Offset = 2166136261;
            protected uint CurrentHashValue;
            public FNV1a()
            {
                this.HashSizeValue = 32;
                this.Initialize();
            }
            public override void Initialize()
            {
                this.CurrentHashValue = Offset;
            }
            protected override void HashCore(byte[] array, int ibStart, int cbSize)
            {
                int end = ibStart + cbSize;
                for (int i = ibStart; i < end; i++)
                    this.CurrentHashValue = (this.CurrentHashValue ^ array[i]) * FNV1a.Prime;
            }
            protected override byte[] HashFinal()
            {
                return BitConverter.GetBytes(this.CurrentHashValue);
            }
        }

    实现修改后的算法

    View Code
     public class ModifiedFNV : FNV1a
        {
            protected override byte[] HashFinal()
            {
                this.CurrentHashValue += this.CurrentHashValue << 13;
                this.CurrentHashValue ^= this.CurrentHashValue >> 7;
                this.CurrentHashValue += this.CurrentHashValue << 3;
                this.CurrentHashValue ^= this.CurrentHashValue >> 17;
                this.CurrentHashValue += this.CurrentHashValue << 5;
    
                return base.HashFinal();
                //   return base.HashFinal 
            }
        }

    节点均衡类

    View Code
     public sealed class DefaultNodeLocator
        {
            private List<string> servers = new List<string>();
            public void Initialize(List<string> nodes)
            {
                this.servers = nodes;
            }
    
            public string Locate(string key)
            {
                uint itemKeyHash = BitConverter.ToUInt32(new ModifiedFNV().ComputeHash(Encoding.Unicode.GetBytes(key)), 0);
                return this.servers[Convert.ToInt16(itemKeyHash % servers.Count)];
            }
    
            private static List<uint> GenerateKeys(string node, int numberOfKeys)
            {
                const int KeyLength = 4;
                const int PartCount = 1;
                List<uint> k = new List<uint>(PartCount * numberOfKeys);
                for (int i = 0; i < numberOfKeys; i++)
                {
                    byte[] data = new ModifiedFNV().ComputeHash(Encoding.ASCII.GetBytes(String.Concat(node, "-", i)));
                    for (int h = 0; h < PartCount; h++)
                        k.Add(BitConverter.ToUInt32(data, h * KeyLength));
                }
                return k;
            }
        }

    实现demo

      class Program
        {
            static void Main(string[] args)
            {
                List<string> servers = new List<string>(new string[] { 
                    "A", "B", 
                    "C", "D" });
                Dictionary<string, List<string>> cache = new Dictionary<string, List<string>>();
    
                DefaultNodeLocator locator = new DefaultNodeLocator();
                locator.Initialize(servers);
                Init(locator, servers, cache);
    
                Console.WriteLine("实例的个数{0}", cache.Count);
                Info(cache);
    
                Console.WriteLine("测试某一个实例发生了问题");
                string s = servers[0];
                var removed = cache[s];
                cache.Remove(s);
                servers.Remove(s);
                Test(locator, cache);
    
                Console.WriteLine("测试需要增加一个实例");
    
                servers = new List<string>(new string[] { 
                    "A", "B", 
                    "C", "D", "E" });
    
                locator = new DefaultNodeLocator();
                locator.Initialize(servers);
                cache.Add(s, removed);
                Test(locator, cache);
    
                Console.WriteLine("经过一段时间后的节点分配情况");
                cache = new Dictionary<string, List<string>>();
                Init(locator, servers, cache);
                Info(cache);
    
                Console.ReadLine();
            }
    
            static void Test(DefaultNodeLocator locator, Dictionary<string, List<string>> cache)
            {
                Console.Write("没有命中的节点:");
                int failed = 0;
                for (int i = 0; i < 100; i++)
                {
                    string key = i.ToString();
                    string value = i.ToString();
                    string server = locator.Locate(key);
                    if (!cache.ContainsKey(server) || !cache[server].Contains(key))
                    {
                        failed++;
                        Console.Write(string.Format("{0} -> {1}", key, server) + ",");
                    }
                }
                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("命中率为 {0} %", 100 - failed);
                Console.ForegroundColor = ConsoleColor.Gray;
            }
    
            static void Init(DefaultNodeLocator locator, List<string> servers, Dictionary<string, List<string>> cache)
            {
    
                for (int i = 0; i < 100; i++)
                {
                    string key = i.ToString();
                    string value = i.ToString();
                    string server = locator.Locate(key);
                    if (!cache.ContainsKey(server))
                        cache.Add(server, new List<string>());
                    cache[server].Add(value);
                }
            }
    
            static void Info(Dictionary<string, List<string>> cache)
            {
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("每一个实例缓存分布情况如下:");
                Console.ForegroundColor = ConsoleColor.Gray;
                foreach (var server in cache)
                {
                    StringBuilder sb = new StringBuilder();
                    var values = server.Value;
                    sb.Append(string.Format("{0} ({1}values) : ", server.Key, values.Count));
                    foreach (var value in values)
                    {
                        sb.Append(value + ",");
                    }
                    Console.WriteLine(sb.ToString());
                }
            }
        }
  • 相关阅读:
    java中讲讲PrintStream的用法,举例?
    Spark Scala当中reduceByKey的用法
    springboot与ActiveMQ整合
    solr(六): 集群
    zookeeper集群
    solr(五): centos中, 整合 tomcat&solr
    springboot redis(单机/集群)
    redis 五种数据类型
    redis 集群搭建: redis-cluster
    redis 持久化
  • 原文地址:https://www.cnblogs.com/visionwang/p/2779975.html
Copyright © 2020-2023  润新知