Package com.agoragames.leaderboard

Source Code of com.agoragames.leaderboard.Leaderboard

package com.agoragames.leaderboard;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Tuple;
import redis.clients.jedis.Transaction;
import redis.clients.jedis.TransactionBlock;

public class Leaderboard {
 
  public static final String VERSION = "2.0.0";
  public static final int DEFAULT_PAGE_SIZE = 25;
  public static final String DEFAULT_REDIS_HOST = "localhost";
  public static final int DEFAULT_REDIS_PORT = 6379;

  private Jedis _jedis;
  private String _leaderboardName;
  private int _pageSize;
 
  /**
   * Create a leaderboard using the default host, default port, and default page size
   *
   * @param leaderboardName Name of the leaderboard
   */
  public Leaderboard(String leaderboardName) {
    this(leaderboardName, DEFAULT_REDIS_HOST, DEFAULT_REDIS_PORT, DEFAULT_PAGE_SIZE);
  }
 
  /**
   * Create a leaderboard with a given name, host, port and page size
   *
   * @param leaderboardName Name of the leaderboard
   * @param host Redis host
   * @param port Redis port
   * @param pageSize Page size
   */
  public Leaderboard(String leaderboardName, String host, int port, int pageSize) {
    this(leaderboardName, pageSize, new Jedis(host, port));
  }
 
  /**
   * Create a leaderboard with a given name, page size and existing Redis connection
   *
   * @param leaderboardName Name of the leaderboard
   * @param pageSize Page size
   * @param redisConnection Redis connection
   */
  public Leaderboard(String leaderboardName, int pageSize, Jedis redisConnection) {
      _leaderboardName = leaderboardName;
      _pageSize = pageSize;
     
      if (_pageSize < 1) {
          _pageSize = DEFAULT_PAGE_SIZE;
      }
     
      _jedis = redisConnection;
  }
 
  /**
   * Get the leaderboard name
   *
   * @return Leaderboard name
   */
  public String getLeaderboardName() {
    return _leaderboardName;   
  }

  /**
   * Get the page size
   *
   * @return Page size
   */
  public long deleteLeaderboard() {
    return deleteLeaderboardNamed(_leaderboardName);
  }

  /**
   * Get the page size
   *
   * @return Page size
   */
  public long deleteLeaderboardNamed(String leaderboardName) {
    return _jedis.del(leaderboardName);
  }
   
  /**
   * Get the page size
   *
   * @return Page size
   */
  public int getPageSize() {
    return _pageSize;
  }
 
  /**
   * Set the page size
   *
   * @param pageSize Page size
   */
  public void setPageSize(int pageSize) {
    if (pageSize < 1) {
      pageSize = DEFAULT_PAGE_SIZE;
    }
   
    _pageSize = pageSize;
  }
 
  /**
   * Disconnect from the Redis instance
   */
  public void disconnect() {
    _jedis.disconnect();
  }
 
  /**
   * Return the total # of members in the current leaderboard
   *
   * @return Total # of members in the current leaderboard
   */
  public long totalMembers() {
    return this.totalMembersIn(_leaderboardName);
  }
 
  /**
   * Return the total # of members in the named leaderboard
   *
   * @param leaderboardName Leaderboard
   * @return Total # of members in the leaderboard
   */
  public long totalMembersIn(String leaderboardName) {
    return _jedis.zcard(leaderboardName);
  }
 
  /**
   * Return the total # of pages in the current leaderboard
   *
   * @return Total # of pages in the current leaderboard
   */
  public int totalPages() {
    return totalPagesIn(_leaderboardName, null);
  }
 
  /**
   * Return the total # of pages in the named leaderboard
   *
   * @param leaderboardName Leaderboard
   * @param pageSize Page size
   * @return Total # of pages in the named leaderboard
   */
  public int totalPagesIn(String leaderboardName, Integer pageSize) {
    if (pageSize == null) {
      pageSize = _pageSize;
    }
   
    return (int) Math.ceil((float) totalMembersIn(_leaderboardName) / (float) pageSize);   
  }
 
  /**
   * Return the total # of members in the current leaderboard in a score range
   * 
   * @param minScore Minimum score
   * @param maxScore Maximum score
   * @return Total # of members in the current leaderboard in a score range
   */
  public long totalMembersInScoreRange(double minScore, double maxScore) {
    return totalMembersInScoreRangeIn(_leaderboardName, minScore, maxScore);
  }
 
  /**
   * Return the total # of members in the named leaderboard in a score range
   * 
   * @param leaderboardName Leaderboard
   * @param minScore Minimum score
   * @param maxScore Maximum score
   * @return Total # of members in the named leaderboard in a score range
   */
  public long totalMembersInScoreRangeIn(String leaderboardName, double minScore, double maxScore) {
    return _jedis.zcount(leaderboardName, minScore, maxScore);
  }

  /**
   * Rank a member in the current leaderboard
   *
   * @param member Member
   * @param score Score
   * @return
   */
  public long rankMember(String member, double score) {
    return this.rankMemberIn(_leaderboardName, member, score);
  }

  /**
   * Rank a member in the named leaderboard
   *
   * @param leaderboardName Leaderboard
   * @param member Member
   * @param score Score
   * @return
   */
  public long rankMemberIn(String leaderboardName, String member, double score) {
    return _jedis.zadd(leaderboardName, score, member);
  }
 
  /**
   * Retrieve the score for a member in the current leaderboard
   *
   * @param member Member
   * @return Member score
   */
  public double scoreFor(String member) {
    return scoreForIn(_leaderboardName, member);
  }
 
  /**
   * Retrieve the score for a member in the named leaderboard
   *
   * @param leaderboardName Leaderboard
   * @param member Member
   * @return Member score
   */
  public double scoreForIn(String leaderboardName, String member) {
    return _jedis.zscore(leaderboardName, member);
  }
 
  /**
   * Change the score for a member by a certain delta in the current leaderboard
   *
   * @param member Member
   * @param delta Score delta
   * @return Updated score
   */
  public double changeScoreFor(String member, double delta) {
    return changeScoreForMemberIn(_leaderboardName, member, delta);
  }
 
  /**
   * Change the score for a member by a certain delta in the named leaderboard
   *
   * @param leaderboardName Leaderboard
   * @param member Member
   * @param delta Score delta
   * @return Updated score
   */
  public double changeScoreForMemberIn(String leaderboardName, String member, double delta) {
    return _jedis.zincrby(_leaderboardName, delta, member);
  }
 
  /**
   * Check to see if member is in the current leaderboard
   *
   * @param member Member
   * @return true if member is in the current leaderboard, false otherwise
   */
  public boolean checkMember(String member) {
    return checkMemberIn(_leaderboardName, member);
  }
 
  /**
   * Check to see if member is in the named leaderboard
   *
   * @param leaderboardName Leaderboard
   * @param member Member
   * @return true if member is in the named leaderboard, false otherwise
   */
  public boolean checkMemberIn(String leaderboardName, String member) {
    return !(_jedis.zscore(leaderboardName, member) == null);
  }
 
  /**
   * Retrieve the rank for a member in the current leaderboard
   *
   * @param member Member
   * @param useZeroIndexForRank Use zero-based index for rank
   * @return Rank for member in the current leaderboard
   */
  public long rankFor(String member, boolean useZeroIndexForRank) {
    return rankForIn(_leaderboardName, member, useZeroIndexForRank);
  }
 
  /**
   * Retrieve the rank for a member in the named leaderboard
   *
   * @param leaderboardName Leaderboard
   * @param member Member
   * @param useZeroIndexForRank Use zero-based index for rank
   * @return Rank for member in the named leaderboard
   */
  public long rankForIn(String leaderboardName, String member, boolean useZeroIndexForRank) {
    if (useZeroIndexForRank) {
      return _jedis.zrevrank(leaderboardName, member);
    } else {
      return (_jedis.zrevrank(leaderboardName, member) + 1);
    }   
  }
 
  /**
   * Remove members from the current leaderboard in a given score range
   *
   * @param minScore Minimum score
   * @param maxScore Maximum score
   * @return
   */
  public long removeMembersInScoreRange(double minScore, double maxScore) {
    return removeMembersInScoreRangeIn(_leaderboardName, minScore, maxScore);
  }
 
  /**
   * Remove members from the named leaderboard in a given score range
   *
   * @param leaderboardName Leaderboard
   * @param minScore Minimum score
   * @param maxScore Maximum score
   * @return
   */
  public long removeMembersInScoreRangeIn(String leaderboardName, double minScore, double maxScore) {
    return _jedis.zremrangeByScore(leaderboardName, minScore, maxScore);
  }
 
  /**
   * Retrieve score and rank for a member in the current leaderboard
   *
   * @param member Member
   * @param useZeroIndexForRank Use zero-based index for rank
   * @return Score and rank for a member in the current leaderboard
   */
  public Hashtable<String, Object> scoreAndRankFor(String member, boolean useZeroIndexForRank) {
    return scoreAndRankForIn(_leaderboardName, member, useZeroIndexForRank);
  }
 
  /**
   * Retrieve score and rank for a member in the named leaderboard
   *
   * @param leaderboardName Leaderboard
   * @param member Member
   * @param useZeroIndexForRank Use zero-based index for rank
   * @return Score and rank for a member in the named leaderboard
   */
  public Hashtable<String, Object> scoreAndRankForIn(String leaderboardName, String member, boolean useZeroIndexForRank) {
    Hashtable<String, Object> data = new Hashtable<String, Object>();
   
    Transaction transaction = _jedis.multi();
        transaction.zscore(leaderboardName, member);
        transaction.zrevrank(leaderboardName, member);
        List<Object> response = transaction.exec();
               
    data.put("member", member);
    data.put("score", response.get(0));   
    if (useZeroIndexForRank) {
        data.put("rank", response.get(1));
    } else {
        data.put("rank", (Long) response.get(1) + 1);
    }
   
    return data;
  }
 
  /**
   * Retrieve a page of leaders as a list of LeaderData in the current leaderboard
   *
   * @param currentPage Page
   * @param useZeroIndexForRank Use zero-based index for rank
   * @return Page of leaders as a list of LeaderData in the current leaderboard
   */
  public List<LeaderData> leadersIn(int currentPage, boolean useZeroIndexForRank) {
    return leadersIn(_leaderboardName, currentPage, useZeroIndexForRank, _pageSize);
  }
 
  /**
   * Retrieve a page of leaders as a list of LeaderData in the named leaderboard
   *
   * @param leaderboardName Leaderboard
   * @param currentPage Page
   * @param useZeroIndexForRank Use zero-based index for rank
   * @param pageSize Page size
   * @return Page of leaders as a list of LeaderData in the named leaderboard
   */
  public List<LeaderData> leadersIn(String leaderboardName, int currentPage, boolean useZeroIndexForRank, int pageSize) {
    if (currentPage < 1) {
      currentPage = 1;
    }
   
    if (pageSize < 1) {
      pageSize = DEFAULT_PAGE_SIZE;
    }
   
    if (currentPage > totalPagesIn(leaderboardName, pageSize)) {
      currentPage = totalPagesIn(leaderboardName, pageSize);
    }
   
    int indexForRedis = currentPage - 1;
    int startingOffset = indexForRedis * pageSize;
    if (startingOffset < 0) {
      startingOffset = 0;
    }
    int endingOffset = (startingOffset + pageSize) - 1;
       
    Set<Tuple> rawLeaderData = _jedis.zrevrangeWithScores(leaderboardName, startingOffset, endingOffset);
    return massageLeaderData(leaderboardName, rawLeaderData, useZeroIndexForRank)
  }
 
  /**
   * Retrieve leaders around a given member in the current leaderboard as a list of LeaderData
   *
   * @param member Member
   * @param useZeroIndexForRank Use zero-based index for rank
   * @return Leaders around a given member in the current leaderboard as a list of LeaderData
   */
  public List<LeaderData> aroundMe(String member, boolean useZeroIndexForRank) {
    return aroundMeIn(_leaderboardName, member, useZeroIndexForRank, _pageSize);
  }
 
  /**
   * Retrieve leaders around a given member in the named leaderboard as a list of LeaderData
   *
   * @param leaderboardName Leaderboard
   * @param member Member
   * @param useZeroIndexForRank Use zero-based index for rank
   * @param pageSize Page size
   * @return Leaders around a given member in the named leaderboard as a list of LeaderData
   */
  public List<LeaderData> aroundMeIn(String leaderboardName, String member, boolean useZeroIndexForRank, int pageSize) {
    long reverseRankForMember = _jedis.zrevrank(leaderboardName, member);
   
    if (pageSize < 1) {
      pageSize = DEFAULT_PAGE_SIZE;
    }

    int startingOffset = (int) reverseRankForMember - (pageSize / 2);
    if (startingOffset < 0) {
      startingOffset = 0;
    }
    int endingOffset = (startingOffset + pageSize) - 1;
 
    Set<Tuple> rawLeaderData = _jedis.zrevrangeWithScores(leaderboardName, startingOffset, endingOffset);
    return massageLeaderData(leaderboardName, rawLeaderData, useZeroIndexForRank)
  }
 
  /**
   * Retrieve a list of LeaderData objects for a list of members in the current leaderboard
   *
   * @param members List of member names
   * @param useZeroIndexForRank Use zero-based index for rank
   * @return List of LeaderData objects for a list of members in the current leaderboard
   */
  public List<LeaderData> rankedInList(List<String> members, boolean useZeroIndexForRank) {
    return rankedInListIn(_leaderboardName, members, useZeroIndexForRank);
  }
 
  /**
   * Retrieve a list of LeaderData objects for a list of members in the named leaderboard
   *
   * @param leaderboardName Leaderboard
   * @param members List of member names
   * @param useZeroIndexForRank Use zero-based index for rank
   * @return List of LeaderData objects for a list of members in the named leaderboard
   */
  public List<LeaderData> rankedInListIn(String leaderboardName, List<String> members, boolean useZeroIndexForRank) {
    List<LeaderData> leaderData = new ArrayList<LeaderData>();
   
    Iterator<String> membersIterator = members.iterator();
    while (membersIterator.hasNext()) {
      String member = membersIterator.next();
      LeaderData memberData = new LeaderData(member, scoreForIn(leaderboardName, member), rankForIn(leaderboardName, member, useZeroIndexForRank));
      leaderData.add(memberData);
    }
   
    return leaderData;
  }
   
  /**
   * Massage the leaderboard data into LeaderData objects
   *
   * @param leaderboardName Leaderboard
   * @param memberData Tuple of member and score
   * @param useZeroIndexForRank Use zero-based index for rank
   * @return List of LeaderData objects which contains member, score and rank
   */
  private List<LeaderData> massageLeaderData(String leaderboardName, Set<Tuple> memberData, boolean useZeroIndexForRank) {
    List<LeaderData> leaderData = new ArrayList<LeaderData>();
   
    Iterator<Tuple> memberDataIterator = memberData.iterator();
    while (memberDataIterator.hasNext()) {
      Tuple memberDataTuple = memberDataIterator.next();
      LeaderData leaderDataItem = new LeaderData(memberDataTuple.getElement(), memberDataTuple.getScore(), rankForIn(leaderboardName, memberDataTuple.getElement(), useZeroIndexForRank));
      leaderData.add(leaderDataItem);
    }
   
    return leaderData;
  }
}
TOP

Related Classes of com.agoragames.leaderboard.Leaderboard

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.