org.ublog.benchmark.social.SocialBenchmark.java Source code

Java tutorial

Introduction

Here is the source code for org.ublog.benchmark.social.SocialBenchmark.java

Source

/*******************************************************************************
 * Copyright 2010 Universidade do Minho, Ricardo Vila?a and Francisco Cruz
 * 
 * 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 org.ublog.benchmark.social;

import java.io.UnsupportedEncodingException;
import java.rmi.NotBoundException;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;

import org.ublog.utils.Pair;
import org.ublog.benchmark.BenchOperation;
import org.ublog.benchmark.ComplexBenchMarkClient;
import org.ublog.benchmark.ComplexBenchmark;
import org.ublog.benchmark.StatsCollector;
import org.ublog.benchmark.operations.CollectionOperation;
import org.ublog.benchmark.operations.MultiPutOperation;
import org.ublog.graph.GraphInterface;

import org.ublog.utils.Clock;

public class SocialBenchmark extends ComplexBenchmark {

    public final static String userTable = "users";
    public final static String tweetsTable = "tweets";
    public final static String friendsTimeLineTable = "friendsTimeLine";

    private Logger logger = Logger.getLogger(SocialBenchmark.class);

    //Values defined by configuration file
    private double initialTweetsFactor = 10.0;
    private double probabilitySearchPerTopic = 0.15;
    private double probabilitySearchPerOwner = 0.25;
    private double probabilityGetRecentTweets = 0.05;
    private double probabilityGetFriendsTimeline = 0.45;
    private double probabilityStartFollowing = 0.05;
    private double probabilityStopFollowing = 0.05;

    private int totalSize = 0;
    private boolean missingCreatingTables;
    private boolean missingAddingUsers;

    private int currentUser;
    private int currentTweet;
    private int currentNTweets;

    private BenchOperation currentTweetOp;
    private UserService clouderUserService;
    private int nOperations;

    private Random rndOp;
    private Random rndOwner;
    private Random rndTopic;
    private Random rndStartFollow;

    private double thinkTime;

    private SocialOperationsFactory opFactory;
    private GraphInterface remoteGraphServer;

    private boolean hasInitiated;

    public SocialBenchmark(StatsCollector statsCollector, SocialOperationsFactory opFactory, int sizeTotal,
            int size, int usernameStarter, int nOperations, double thinkTime) {
        super(statsCollector, usernameStarter);
        this.opFactory = opFactory;
        Utils.NUsers = size;
        this.nOperations = nOperations;
        this.thinkTime = thinkTime;
        this.clouderUserService = new UserService();
        this.currentUser = 0;
        this.currentTweet = 0;
        this.currentNTweets = 0;
        this.missingCreatingTables = true;
        this.missingAddingUsers = true;
        this.totalSize = sizeTotal;
    }

    public double getProbabilitySearchPerTopic() {
        return probabilitySearchPerTopic;
    }

    public void setProbabilitySearchPerTopic(double probabilitySearchPerTopic) {
        this.probabilitySearchPerTopic = probabilitySearchPerTopic;
    }

    public double getProbabilitySearchPerOwner() {
        return probabilitySearchPerOwner;
    }

    public void setProbabilitySearchPerOwner(double probabilitySearchPerOwner) {
        this.probabilitySearchPerOwner = probabilitySearchPerOwner;
    }

    public double getProbabilityGetRecentTweets() {
        return probabilityGetRecentTweets;
    }

    public void setProbabilityGetRecentTweets(double probabilityGetRecentTweets) {
        this.probabilityGetRecentTweets = probabilityGetRecentTweets;
    }

    public double getProbabilityGetFriendsTimeline() {
        return probabilityGetFriendsTimeline;
    }

    public void setProbabilityGetFriendsTimeline(double probabilityGetFriendsTimeline) {
        this.probabilityGetFriendsTimeline = probabilityGetFriendsTimeline;
    }

    public double getProbabilityStartFollowing() {
        return probabilityStartFollowing;
    }

    public void setProbabilityStartFollowing(double probabilityStartFollowing) {
        this.probabilityStartFollowing = probabilityStartFollowing;
    }

    public double getProbabilityStopFollowing() {
        return probabilityStopFollowing;
    }

    public void setProbabilityStopFollowing(double probabilityStopFollowing) {
        this.probabilityStopFollowing = probabilityStopFollowing;
    }

    @Override
    public void initialize(Configuration conf) throws ConfigurationException {
        this.initialTweetsFactor = conf.getDouble("benchmark.social.initialTweetsFactor");

        Utils.MAX_MESSAGES_IN_TIMELINE = conf.getInt("benchmark.social.maximumMessagesTimeline");
        Utils.MaxNTweets = conf.getInt("benchmark.social.maximumTweetsPerUser");
        long seedNextOperation = conf.containsKey("benchmark.social.seedNextOperation")
                ? conf.getLong("benchmark.social.seedNextOperation")
                : System.nanoTime();
        long seedOwner = conf.containsKey("benchmark.social.seedOwner") ? conf.getLong("benchmark.social.seedOwner")
                : System.nanoTime();
        long seedTopic = conf.containsKey("benchmark.social.seedTopic") ? conf.getLong("benchmark.social.seedTopic")
                : System.nanoTime();
        long seedStartFollow = conf.containsKey("benchmark.social.seedStartFollow")
                ? conf.getLong("benchmark.social.seedStartFollow")
                : System.nanoTime();

        this.rndOp = new Random(seedNextOperation);
        this.rndOwner = new Random(seedOwner);
        this.rndTopic = new Random(seedTopic);
        this.rndStartFollow = new Random(seedStartFollow);

        this.probabilitySearchPerTopic = conf.getDouble("benchmark.social.probabilities.probabilitySearchPerTopic");
        this.probabilitySearchPerOwner = conf.getDouble("benchmark.social.probabilities.probabilitySearchPerOwner");
        this.probabilityGetRecentTweets = conf
                .getDouble("benchmark.social.probabilities.probabilityGetRecentTweets");
        this.probabilityGetFriendsTimeline = conf
                .getDouble("benchmark.social.probabilities.probabilityGetFriendsTimeline");
        this.probabilityStartFollowing = conf.getDouble("benchmark.social.probabilities.probabilityStartFollowing");
        this.probabilityStopFollowing = conf.getDouble("benchmark.social.probabilities.probabilityStopFollowing");
        if (this.probabilityGetFriendsTimeline + this.probabilityGetRecentTweets + this.probabilitySearchPerOwner
                + this.probabilitySearchPerTopic + this.probabilityStartFollowing
                + this.probabilityStopFollowing > 1) {
            logger.warn("The sum of all probabilities must be less or equal than 1.");
            throw new ConfigurationException("The sum of all probabilities must be less or equal than 1.");
        }

        String serverName = conf.getString("benchmark.server.name");
        int serverPort = conf.getInt("benchmark.server.port");
        this.remoteGraphServer = this.getRemoteGraphServer(serverName, serverPort);
        try {
            this.hasInitiated = this.remoteGraphServer.init(this.totalSize);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    private GraphInterface getRemoteGraphServer(String serverName, int serverPort) {
        if (System.getSecurityManager() == null) {
            System.setSecurityManager(new RMISecurityManager());
        }
        try {
            if (logger.isInfoEnabled()) {
                logger.info("Trying to connect to graph server");
            }
            Registry reg = LocateRegistry.getRegistry(serverName, serverPort);
            System.out.println("reg " + reg.list().toString());
            return (GraphInterface) reg.lookup("Graph");

        } catch (NotBoundException ex) {
            Logger.getLogger("global").log(null, ex);
            return null;
        } catch (RemoteException ex) {
            ex.printStackTrace();
            Logger.getLogger("global").log(null, ex);
            return null;
        }
    }

    public String getPowerLawTag() {
        Random rnd = new Random();
        int val = 0;
        int i = 0;
        try {
            val = rnd.nextInt(this.remoteGraphServer.getSomaGraus()) + 1;
            int sum = 0;
            for (i = 0; i < 64; i++) {
                sum += this.remoteGraphServer.degreeOfGrausTags("topico" + i);
                if (sum >= val) {
                    break;
                }
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return "topico" + i;
    }

    public int getRandomFriend(User myUser) {
        int res;
        try {
            res = this.remoteGraphServer.getRandomFriend(myUser);
        } catch (RemoteException e) {
            e.printStackTrace();
            res = -1;
        }
        if (res == -1)
            return Utils.NUsers;
        else
            return res;
    }

    @Override
    public ComplexBenchMarkClient createNewClient(Clock clock, int clientCount) {
        ComplexBenchMarkClient client;
        try {
            client = new SocialClient(clock, clientCount, this.remoteGraphServer.getClientCount(clientCount),
                    this.nOperations, this.getStatsCollector(), this.thinkTime, this.rndOp, this, this.opFactory);
        } catch (RemoteException e) {
            e.printStackTrace();
            client = null;
        }
        return client;
    }

    @Override
    public boolean hasMoreInitOperations() {
        int userID;
        if (this.hasInitiated == false) {
            try {
                userID = this.remoteGraphServer.getUserID();
                // System.out.println("USERID HASMOREINIT:"+userID);
            } catch (RemoteException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                userID = 1;
            }
            if (logger.isInfoEnabled())
                logger.info("currentUser:" + this.currentUser + ";userID:" + userID + ";currentTweet:"
                        + this.currentTweet + ";currentNTweets:" + this.currentNTweets);
            return this.missingCreatingTables || this.missingAddingUsers || this.currentUser < userID - 1
                    || this.currentTweetOp.hasMoreDBOperations() || this.currentTweet < this.currentNTweets - 1;
        } else
            return false;
    }

    @SuppressWarnings("unchecked")
    @Override
    public CollectionOperation nextInitOperation() throws UnsupportedEncodingException {
        CollectionOperation res;
        if (this.missingCreatingTables) {
            /*
             * TableMetaData<String>
             * metaData=this.collectionsMetadata.get(currentCollection);
             * this.currentCollection++; res=new
             * CreateTableOperation<String>(metaData);
             * this.missingCreatingCollections = false;///////fui q pus
             */
            res = null;
            this.missingCreatingTables = false;
        } else {

            if (missingAddingUsers) {
                int userID;
                try {
                    userID = this.remoteGraphServer.getUserID();
                } catch (RemoteException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    userID = 1;
                }

                Map<String, Pair<Map<String, String>, List<Integer>>> puts = new HashMap<String, Pair<Map<String, String>, List<Integer>>>();
                for (int i = 0; i < userID; i++) {
                    // User currentUser=this.mapUser.get(i);
                    User currentUser;
                    try {
                        currentUser = this.remoteGraphServer.getMapUser(i);
                    } catch (RemoteException e1) {
                        e1.printStackTrace();
                        currentUser = null;
                    }
                    Set<String> followers = new HashSet<String>();
                    Set<String> following = new HashSet<String>();

                    try {
                        followers = this.remoteGraphServer.getFollowers(currentUser);
                        following = this.remoteGraphServer.getFollowing(currentUser);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    /*
                     * for (DefaultEdge
                     * edge:this.graph.incomingEdgesOf(currentUser)) {
                     * followers.
                     * add(this.graph.getEdgeSource(edge).getUsername()); } for
                     * (DefaultEdge
                     * edge:this.graph.outgoingEdgesOf(currentUser)) {
                     * following.
                     * add(this.graph.getEdgeTarget(edge).getUsername()); }
                     */
                    // List<Integer> tags=new ArrayList<Integer>();
                    // tags.add(Utils.getTagUserID(currentUser.getUsername()));
                    puts.put(currentUser.getUsername(),
                            new Pair<Map<String, String>, List<Integer>>(this.clouderUserService.newUser(
                                    currentUser, Utils.toString(followers), Utils.toString(following)), null));
                }
                CollectionOperation tmp = new MultiPutOperation(null, "users", puts);
                tmp.setInit(true);
                res = tmp;
                this.missingAddingUsers = false;
                this.currentUser = 0;
                this.currentTweet = 0;
                try {
                    // this.currentNTweets=(int)
                    // Math.ceil(this.graph.outDegreeOf(this.mapUser.get(this.currentUser))*initialTweetsFactor);
                    this.currentNTweets = (int) Math
                            .ceil(this.remoteGraphServer.getOutDegreeOf(currentUser) * initialTweetsFactor);
                    // this.currentTweetOp=this.getNewTweetOperation(this.mapUser.get(this.currentUser),
                    // null);
                    this.currentTweetOp = this.getNewTweetOperation(this.remoteGraphServer.getMapUser(currentUser),
                            null);
                    // System.out.println("currentNTweets: "+currentNTweets);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                this.currentTweetOp.setInit(true);
                // System.out.println("SET INIT op:"+this.currentTweetOp);
            } else {

                if (this.currentTweetOp.hasMoreDBOperations()) {
                    res = this.currentTweetOp.getNextDBOperation();
                } else {
                    this.currentTweet++;
                    if (this.currentTweet < this.currentNTweets) {
                        try {
                            // this.currentTweetOp=this.getNewTweetOperation(this.mapUser.get(this.currentUser),
                            // null);
                            this.currentTweetOp = this
                                    .getNewTweetOperation(this.remoteGraphServer.getMapUser(currentUser), null);
                        } catch (RemoteException e) {
                            e.printStackTrace();
                        }
                        this.currentTweetOp.setInit(true);
                        // System.out.println("SET INIT op:"+this.currentTweetOp);
                        res = this.currentTweetOp.getNextDBOperation();
                    } else {
                        this.currentUser++;
                        this.currentTweet = 0;
                        try {
                            // this.currentNTweets=(int)
                            // Math.ceil(this.graph.outDegreeOf(this.mapUser.get(this.currentUser))*initialTweetsFactor);
                            this.currentNTweets = (int) Math
                                    .ceil(this.remoteGraphServer.getOutDegreeOf(currentUser) * initialTweetsFactor);
                            // this.currentTweetOp=this.getNewTweetOperation(this.mapUser.get(this.currentUser),
                            // null);
                            this.currentTweetOp = this
                                    .getNewTweetOperation(this.remoteGraphServer.getMapUser(currentUser), null);
                        } catch (RemoteException e) {
                            e.printStackTrace();
                        }
                        this.currentTweetOp.setInit(true);

                        // System.out.println("SET INIT op:"+this.currentTweetOp);
                        res = this.currentTweetOp.getNextDBOperation();
                    }
                }
            }
        }
        if (logger.isInfoEnabled())
            logger.info("Next Init Operation is:" + res);
        return res;
    }

    public String getNextStartFollowingUser(User user) {
        // Da o utilizador com mais seguidores ao qual o user ainda nao segue
        String res = null;
        while (true) {
            int userID = this.rndStartFollow.nextInt(Utils.NUsers);
            boolean containsEdge;
            try {
                containsEdge = this.remoteGraphServer.graphContainsEdge(user, userID);
            } catch (RemoteException e) {
                e.printStackTrace();
                containsEdge = false;
            }
            if (!containsEdge) {
                try {
                    res = this.remoteGraphServer.getMapUser(userID).getUsername();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;
            }
        }
        return res;
    }

    public String getNextStopFollowingUser(User user) {
        // Da o utilizador com menos seguidores ao qual o user ainda segue
        try {
            return this.remoteGraphServer.getNextStopFollowingUser(user);
        } catch (RemoteException e) {
            e.printStackTrace();
            return null;
        }
    }

    public BenchOperation getNewTweetOperation(User user, SocialClient client) {
        // System.out.println("NEW TWEET OP");
        double hasOwner = rndOwner.nextDouble();
        double hasTopic = rndTopic.nextDouble();
        // System.out.println("TAGS PROB: "+hasOwner+";"+hasTopic);
        Set<String> tags = new HashSet<String>();
        if (hasTopic <= 0.05) // 0.05
        {
            tags.add(this.getPowerLawTag());
        }
        if (hasOwner <= 0.35) {
            int friend = this.getRandomFriend(user);
            tags.add("user" + friend);
            // System.out.println("user"+friend);
        }
        Message tweet = new Message();
        // tweet.setDate(new Date());
        tweet.setDate(Utils.getTimeUUID());
        tweet.setText("qq");
        tweet.setUser(user.getUsername());
        return this.opFactory.getNewTweetOperation(client, tweet, tags);
    }
}