zoukankan      html  css  js  c++  java
  • 一般性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());
                }
            }
        }
  • 相关阅读:
    Centos7配置编译Tenflow1.15 GPU版本笔记
    今年有哪些便宜的国外域名注册商?
    VPS,域名,主机,建站主题,2020黑色星期五优惠大放送
    这些个挂机项目,赚点小钱玩玩
    WPF管理系统开发框架搭建指南,2020从入门到放弃
    智和信通助力荆门电教馆及六所市直学校实现网络智能化运维管理
    智和网管平台政企信创网管监控运维可视化方案
    智和网管平台与统信操作系统完成认证 强力支撑信创国产替代进程
    GIT基础操作与理解
    高数复习一(数列极限)
  • 原文地址:https://www.cnblogs.com/visionwang/p/2779975.html
Copyright © 2011-2022 走看看