package models.dao; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.Callable; import javax.inject.Inject; import javax.inject.Singleton; import models.User; import models.UserFollow; import models.UserFollowPK; import play.utils.cache.InterimCache; import play.utils.dao.CachedDAO; import play.utils.dao.TimestampListener; import com.avaje.ebean.Page; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import play.utils.dao.*; @Singleton public class UserFollowDAO extends CachedDAO<UserFollowPK, UserFollow> { public static final int PAGE_SIZE = 20; protected InterimCache<Integer> followerCountCache = new InterimCache<Integer>("UserFollowerCountCache", 86400);//24 hrs protected InterimCache<Page<User>> followerPageCache = new InterimCache<Page<User>>("UserFollowerPageCache", 86400);//24 hrs protected InterimCache<Page<User>> followingPageCache = new InterimCache<Page<User>>("UserFollowingPageCache", 86400);//24 hrs protected InterimCache<List<UserFollow>> followingCache = new InterimCache<List<UserFollow>>("FollowingCache", 86400);//24 hrs protected Multimap<String, String> userPages = HashMultimap.create(); private UserDAO userDAO; @Inject public UserFollowDAO(UserDAO userDAO) { super(UserFollowPK.class, UserFollow.class); this.userDAO = userDAO; addListener(new TimestampListener<UserFollowPK, UserFollow>()); addListener(new UserFollowDAOFollowCacheCleaner(this)); } public UserFollow get(String sourceKey, String targetKey) { UserFollowPK key = new UserFollowPK(sourceKey, targetKey); return find().byId(key); } public Integer getFollowerCount(final User u) { String key = u.getKey(); final Integer count = followerCountCache.get("." + key, new Callable<Integer>() { public Integer call() throws Exception { return find.where().eq("target_key", u.getKey()).findRowCount(); } }); return count; } public Integer getFollowingCount(final User u) { String key = u.getKey(); final List<UserFollow> count = followingCache.get("." + key, new Callable<List<UserFollow>>() { public List<UserFollow> call() throws Exception { return find.where().eq("source_key", u.getKey()).findList(); } }); return count.size(); } public Page<User> getFollowerUsers(final User u, final int page) { final String key = u.getKey(); final String cacheKey = "." + key + ".pg." + page; final Page<User> count = followerPageCache.get(cacheKey, new Callable<Page<User>>() { public Page<User> call() throws Exception { userPages.put(key, cacheKey); Page<UserFollow> followPage = find.page(page, PAGE_SIZE, "created_on desc", "target_key", u.getKey()); PageAdapter<UserFollow, User> userPage = new UserFollowerPageAdapter(followPage, userDAO); return userPage; } }); return count; } public List<String> getAllFollowingsKeys(final User u){ final String key = u.getKey(); final List<UserFollow> count = followingCache.get("." + key, new Callable<List<UserFollow>>() { public List<UserFollow> call() throws Exception { return find.where().eq("source_key", u.getKey()).findList(); } }); List<String> keys=new ArrayList<String>(); for(UserFollow userFollow: count){ keys.add(userFollow.getKey().getTargetKey()); } return keys; } public Page<User> getFollowingUsers(final User u, final int page) { final String key = u.getKey(); final String cacheKey = "." + key + ".pg." + page; final Page<User> count = followingPageCache.get(cacheKey, new Callable<Page<User>>() { public Page<User> call() throws Exception { userPages.put(key, cacheKey); Page<UserFollow> followPage = page(page, PAGE_SIZE, "created_on desc", "source_key", u.getKey()); PageAdapter<UserFollow, User> userPage = new UserFollowingPageAdapter(followPage, userDAO); return userPage; } }); return count; } public void cleanCache(String key) { followerCountCache.set("." + key, null); followingCache.set("." + key, null); Collection<String> pageKeys = userPages.get(key); for (String pageKey : pageKeys) { followerPageCache.set(pageKey, null); followingPageCache.set(pageKey, null); } userPages.removeAll(key); } }