/** *Copyright [2009-2010] [dennis zhuang(killme2008@gmail.com)] *Licensed under the Apache License, Version 2.0 (the "License"); *you may not use this file except in compliance with the License. *You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 *Unless required by applicable law or agreed to in writing, *software distributed under the License is distributed on an "AS IS" BASIS, *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, *either express or implied. See the License for the specific language governing permissions and limitations under the License */ /** *Copyright [2009-2010] [dennis zhuang(killme2008@gmail.com)] *Licensed under the Apache License, Version 2.0 (the "License"); *you may not use this file except in compliance with the License. *You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 *Unless required by applicable law or agreed to in writing, *software distributed under the License is distributed on an "AS IS" BASIS, *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, *either express or implied. See the License for the specific language governing permissions and limitations under the License */ package net.rubyeye.xmemcached.impl; import java.util.ArrayList; import java.util.Collection; import java.util.List; import net.rubyeye.xmemcached.HashAlgorithm; import net.rubyeye.xmemcached.networking.MemcachedSession; import com.google.code.yanf4j.core.Session; /** * Election hash strategy * * @author dennis * */ public class ElectionMemcachedSessionLocator extends AbstractMemcachedSessionLocator { private transient volatile List<Session> sessions; private final HashAlgorithm hashAlgorithm; public ElectionMemcachedSessionLocator() { this.hashAlgorithm = HashAlgorithm.ELECTION_HASH; } public ElectionMemcachedSessionLocator(HashAlgorithm hashAlgorithm) { super(); this.hashAlgorithm = hashAlgorithm; } public Session getSessionByKey(String key) { // copy on write List<Session> copySessionList = new ArrayList<Session>(this.sessions); Session result = this.getSessionByElection(key, copySessionList); while (!this.failureMode && (result == null || result.isClosed()) && copySessionList.size() > 0) { copySessionList.remove(result); result = this.getSessionByElection(key, copySessionList); } return result; } private Session getSessionByElection(String key, List<Session> copySessionList) { Session result = null; long highScore = 0; for (Session session : copySessionList) { long hash = 0; if (session instanceof MemcachedTCPSession) { MemcachedSession tcpSession = (MemcachedSession) session; for (int i = 0; i < tcpSession.getWeight(); i++) { hash = this.hashAlgorithm.hash(session .getRemoteSocketAddress().toString() + "-" + i + key); if (hash > highScore) { highScore = hash; result = session; } } } else { hash = this.hashAlgorithm.hash(session.getRemoteSocketAddress() .toString() + key); } if (hash > highScore) { highScore = hash; result = session; } } return result; } public void updateSessions(Collection<Session> list) { this.sessions = new ArrayList<Session>(list); } }