/* * festivoice * * Copyright 2009 FURUHASHI Sadayuki, KASHIHARA Shuzo, SHIBATA Yasuharu * * 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.festivoice; import java.lang.*; import java.util.*; import java.net.*; public class ChannelInfo implements IChannelInfo { private String name; private HashMap<InetSocketAddress, UserInfo> users; private HashMap<InetSocketAddress, UserInfo> usersCache; /** * @param n チャンネル名 */ ChannelInfo(String n) { name = n; users = new LinkedHashMap<InetSocketAddress, UserInfo>(); updateUsersCache(); } public String getChannelName() { return name; } public Iterable<? extends IUserInfo> getUsers() { return usersCache.values(); } /** * ユーザーが登録されていなければ登録し、されていれば * タイムアウトカウントをリセットする(keepalive)。 * @return ユーザーが新規登録されたらtrue */ public boolean userData(String name, InetSocketAddress addr) { // UserInfo user = new UserInfo(name, addr); // 新規優先 //user = users.put(addr, user); //return user == null; // 新規優先順番重視 // user = users.putIfAbsent(addr, user); // if(user != null) { // user.userData(name); // return false; // } else { // return true; // } // 既存優先 //user = users.putIfAbsent(user, addr); //if(user != null) { // user.resetTimeout(); // return false; //} else { // return true; //} UserInfo userInfo = usersCache.get(addr); if(userInfo != null) { userInfo.userData(name); return false; } synchronized(users) { userInfo = users.get(addr); if(userInfo != null) { userInfo.userData(name); return false; } userInfo = new UserInfo(addr, name); users.put(addr, userInfo); updateUsersCache(); return true; } } private void updateUsersCache() { usersCache = (LinkedHashMap)users.clone(); } /** * タイムアウトカウントをインクリメントし、limitに達したユーザーを削除する。 * @return ユーザーが1人でも削除されたらnot nil */ public Iterator<UserInfo> stepTimeout(int limit) { boolean updated = false; List<UserInfo> removed = null; synchronized(users) { for(Iterator<UserInfo> it = users.values().iterator(); it.hasNext(); ) { UserInfo user = it.next(); if(user.stepTimeout() > limit) { if(removed == null) { removed = new ArrayList<UserInfo>(); } removed.add(user); it.remove(); } } if(removed != null) { updateUsersCache(); return removed.iterator(); } return null; } } public boolean isEmpty() { return usersCache.isEmpty(); } }