IMemcachedNode INodeLocator.Locate(string key) { if (key == null) { throw new ArgumentNullException("key"); } var id = this._lookupData; switch (id.Servers.Length) { case 0: return(null); case 1: var tmp = id.Servers[0]; return(tmp.IsAlive ? tmp : null); } var node = KetamaNodeLocator.LocateNode(id, this.GetKeyHash(key)); // if the result is not alive then try to mutate the item key and // find another node this way we do not have to reinitialize every // time a node dies/comes back // (DefaultServerPool will resurrect the nodes in the background without affecting the hashring) if (!node.IsAlive) { for (var i = 0; i < id.Servers.Length; i++) { // -- this is from spymemcached so we select the same node for the same items var tmpKey = (ulong)GetKeyHash(i + key); tmpKey += (uint)(tmpKey ^ (tmpKey >> 32)); tmpKey &= 0xffffffffL; /* truncate to 32-bits */ // -- end node = KetamaNodeLocator.LocateNode(id, (uint)tmpKey); if (node.IsAlive) { return(node); } } } return(node.IsAlive ? node : null); }
public void TestLocator() { String[] servers = new[]{ "10.0.1.1:11211", "10.0.1.2:11211", "10.0.1.3:11211", "10.0.1.4:11211", "10.0.1.5:11211", "10.0.1.6:11211", "10.0.1.7:11211", "10.0.1.8:11211"}; var nodes = servers. Select(s => new MockNode(new IPEndPoint(IPAddress.Parse(s.Substring(0, s.IndexOf(":"))), 11211))). Cast<IMemcachedNode>(). ToList(); IMemcachedNodeLocator ketama = new KetamaNodeLocator(); ketama.Initialize(nodes.ToList()); foreach (var pair in exp) { var node = ketama.Locate(pair[0]); Assert.AreEqual(node.EndPoint.ToString(), pair[1]); } }