文章投票

  

package com.smart.InAction;

import com.sun.xml.internal.bind.v2.runtime.unmarshaller.Intercepter;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.ZParams;

import java.util.*;

public class Papper {
    private static final int ONE_WEEK_INSECONDS=7 * 86400;
    private static final int VOTE_SCORE =432;
    private static final int ARTICLES_PER_PAGE =25;

    public static void main(String[] args){
        new Papper().run();
    }

    public void run(){
        Jedis conn = new Jedis("localhost");
        conn.auth("admin");
        conn.select(0);

        String articleId = postArticle(conn, "username", "A title", "http://www.google.com");
        System.out.println("We posted a new article with id: " + articleId);
        System.out.println("Its HASH looks like:");
        Map<String, String> artilceData = conn.hgetAll("article:"+articleId);
        for(Map.Entry<String,String> entry: artilceData.entrySet()){
            System.out.println("   "+entry.getKey()+"  "+entry.getValue());
        }
        System.out.println();

        articleVote(conn,"other_user","article:"+articleId);
        String votes = conn.hget("article:" + articleId, "votes");
        System.out.println("We voted for the article, it now has votes: " + votes);
        assert Integer.parseInt(votes)>1;

        System.out.println("The currently highest-scoring articles are:");
        List<Map<String, String>> articles = getArticles(conn, 1);
        printArticles(articles);
        assert articles.size()>=1;

        addGroups(conn,articleId,new String[]{"new-group"});
        System.out.println("We added the article to a new group, other articles include:");
        articles = getGroupArticles(conn, "new-group", 1);
        printArticles(articles);
        assert articles.size() >= 1;
    }

    /**
     * 发布文章
     * @param conn
     * @param user
     * @param title
     * @param link
     * @return
     */
    public String postArticle(Jedis conn,String user,String title,String link){
        String articleId = String.valueOf(conn.incr("article"));

        /**
         * set集合记录投票的用户,缓存一周
         */
        String voted="voted:"+articleId;
        conn.sadd(voted,user);
        conn.expire(voted,ONE_WEEK_INSECONDS);
        /**
         *散列存储文章详情
         */
        long now=System.currentTimeMillis()/1000;
        String article="article:"+articleId;
        Map<String, String> articleData = new HashMap<String,String>();
        articleData.put("title",title);
        articleData.put("link",link);
        articleData.put("user",user);
        articleData.put("now",String.valueOf(now));
        articleData.put("votes","1");
        conn.hmset(article,articleData);
        /**
         * 有序集合记录按时间排序与评分排序的文章
         */
        conn.zadd("score:",now+VOTE_SCORE,article);
        conn.zadd("time:",now,article);

        return articleId;
    }

    /***
     * 文章投票
     */
    public void articleVote(Jedis conn,String user,String article){
        /**
         * 时间超过一周的直接返回
         */
        long cutoff=(System.currentTimeMillis()/1000)-ONE_WEEK_INSECONDS;
        if(conn.zscore("time:",article)<cutoff)
            return ;
        /**
         * 投上一票,文章详情增加一票
         * 按分数排序的有序集合分数增加常数
         */
        String articleId = article.substring(article.indexOf(":") + 1);
        if(conn.sadd("voted:"+articleId,user)==1){
            conn.zincrby("score:",VOTE_SCORE,article);
            conn.hincrBy(article,"votes",1);
        }
    }

    /**
     * 按页获取文章
     * @param conn
     * @param page
     * @return
     */
    public List<Map<String,String>> getArticles(Jedis conn,int page){
        return getArticles(conn,page,"score:");
    }

    /**
     *
     * @param conn
     * @param page
     * @param oreder
     * @return
     */
    public List<Map<String,String>> getArticles(Jedis conn,int page,String oreder){
        int start=(page-1)*ARTICLES_PER_PAGE;
        int end=start+ARTICLES_PER_PAGE-1;

        Set<String> ids = conn.zrevrange(oreder, start, end);
        List<Map<String, String>> articles = new ArrayList<>();
        for (String id :ids){
            Map<String, String> articleData = conn.hgetAll(id);
            articleData.put("id",id);
            articles.add(articleData);
        }
        return articles;
    }

    private void printArticles(List<Map<String,String>> articles){
        for(Map<String,String> article : articles){
            System.out.println("  id: " + article.get("id"));
            for (Map.Entry<String,String> entry : article.entrySet()){
                if (entry.getKey().equals("id")){
                    continue;
                }
                System.out.println("    " + entry.getKey() + ": " + entry.getValue());
            }
        }
    }

    public void addGroups(Jedis conn,String articleId,String[] toAdd){
        String article="article:"+articleId;
        for(String group : toAdd){
            conn.sadd("group:"+group,article);
        }
    }

    public List<Map<String,String>> getGroupArticles(Jedis conn,String group,int page){
        return getGroupArticles(conn,group,page,"score:");
    }

    public List<Map<String,String>> getGroupArticles(Jedis conn,String group,int page,String order){
        String key=order+group;
        if(!conn.exists(key)){
            ZParams params = new ZParams().aggregate(ZParams.Aggregate.MAX);
            conn.zinterstore(key,params,"group:"+group,order);
            conn.expire(key,60);
        }
        return getArticles(conn,page,key);
    }

}

  

posted on 2019-03-23 19:41  溪水静幽  阅读(154)  评论(0)    收藏  举报