一般性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());
            }
        }
    }
posted @ 2012-11-20 23:27  visionwang  阅读(2221)  评论(0编辑  收藏  举报