/******************************************************************************* * 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.util.HashSet; import java.util.Random; import java.util.Set; import org.apache.log4j.Logger; import org.ublog.utils.Pair; import org.ublog.utils.Time; import org.ublog.benchmark.BenchOperation; import org.ublog.benchmark.ComplexBenchMarkClient; import org.ublog.benchmark.StatsCollector; import org.ublog.utils.Clock; public class SocialClient extends ComplexBenchMarkClient { private User myUser; private int currentOp; private int nOperations; private StatsCollector statsCollector; private Clock clock; private Time startTime; private Logger logger = Logger.getLogger(SocialClient.class); private double thinkTime; private Random rndOp; private SocialBenchmark socialBenchmark; private SocialOperationsFactory opFactory; public SocialClient(Clock clock, int clientCount, User user, int nOperations, StatsCollector statsCollector, double thinkTime, Random rndOp, SocialBenchmark socialBenchmark, SocialOperationsFactory opFactory) { super(clientCount); this.clock = clock; this.myUser = user; this.nOperations = nOperations; this.statsCollector = statsCollector; this.currentOp = 0; this.thinkTime = thinkTime; this.rndOp = rndOp; this.socialBenchmark = socialBenchmark; this.opFactory = opFactory; } @Override public Pair<BenchOperation, Double> getNextComplexOperation() { this.startTime = this.clock.getTime().add( Time.inMilliseconds(this.thinkTime)); BenchOperation res; double p = rndOp.nextDouble(); if (p < this.socialBenchmark.getProbabilitySearchPerTopic()) { // Probability given by this.socialBenchmark.getProbabilitySearchPerTopic() Set<String> tags = new HashSet<String>(); tags.add(null); tags.add(this.socialBenchmark.getPowerLawTag()); tags.add(null); if (logger.isInfoEnabled()) logger.info("Client with user:" + this.myUser + " generating new search operation per topic with tags:" + tags + "."); res = this.opFactory.getNewSearchPerTopicOperation(this, tags); } else if (p < (this.socialBenchmark.getProbabilitySearchPerTopic()+this.socialBenchmark.getProbabilitySearchPerOwner())) { // Probability given by this.socialBenchmark.getProbabilitySearchPerOwner() Set<String> tags = new HashSet<String>(); tags.add(null); tags.add(null); tags.add("user" + this.myUser.getUsername().substring(4)); if (logger.isInfoEnabled()) logger.info("Client with user:" + this.myUser + " generating new search operation per direct messages with tags:" + tags + ";myID:" + this.myUser.getUsername().substring(4)); res = this.opFactory.getNewSearchPerOwnerOperation(this, tags); } else if (p < (this.socialBenchmark.getProbabilitySearchPerTopic()+this.socialBenchmark.getProbabilitySearchPerOwner()+ this.socialBenchmark.getProbabilityGetRecentTweets())) { // Probability given by this.socialBenchmark.getProbabilityGetRecentTweets() if (logger.isInfoEnabled()) logger.info("Client with user:" + this.myUser + " generating new get recent tweets operation."); res = this.opFactory.getNewGetTweetsOperation(this, this.myUser.getUsername(), 0, 50); } else if (p < (this.socialBenchmark.getProbabilitySearchPerTopic()+this.socialBenchmark.getProbabilitySearchPerOwner()+ this.socialBenchmark.getProbabilityGetRecentTweets()+this.socialBenchmark.getProbabilityGetFriendsTimeline())) { // Probability given by this.socialBenchmark.getProbabilityGetFriendsTimeline() if (logger.isInfoEnabled()) logger.info("Client with user:" + this.myUser + " generating new get friendsTimeLine operation."); res = this.opFactory.getNewGetFriendsTimeLineOperation(this, this.myUser.getUsername(), 0, 100); } else if (p < (this.socialBenchmark.getProbabilitySearchPerTopic()+this.socialBenchmark.getProbabilitySearchPerOwner()+ this.socialBenchmark.getProbabilityGetRecentTweets()+this.socialBenchmark.getProbabilityGetFriendsTimeline()+ this.socialBenchmark.getProbabilityStartFollowing())) { // Probability given by this.socialBenchmark.getProbabilityStartFollowing() String toStartUser = this.socialBenchmark .getNextStartFollowingUser(this.myUser); if (toStartUser != null) { if (logger.isInfoEnabled()) logger.info("Client with user:" + this.myUser + " generating new start follow operation to user:" + toStartUser + "."); res = this.opFactory.getNewStartFollowingOperation(this, this.myUser.getUsername(), toStartUser); } else { if (logger.isInfoEnabled()) logger.info("Client with user:" + this.myUser + " generating new fake get friendsTimeLine operation."); res = this.opFactory.getNewGetFriendsTimeLineOperation(this, this.myUser.getUsername(), 0, 100); } } else if (p < (this.socialBenchmark.getProbabilitySearchPerTopic()+this.socialBenchmark.getProbabilitySearchPerOwner()+ this.socialBenchmark.getProbabilityGetRecentTweets()+this.socialBenchmark.getProbabilityGetFriendsTimeline()+ this.socialBenchmark.getProbabilityStartFollowing()+this.socialBenchmark.getProbabilityStopFollowing())) { // Probability given by this.socialBenchmark.getProbabilityStopFollowing() String toStopUser = this.socialBenchmark .getNextStopFollowingUser(this.myUser); if (toStopUser != null) { if (logger.isInfoEnabled()) logger.info("Client with user:" + this.myUser + " generating new stop follow operation to user:" + toStopUser + "."); res = this.opFactory.getNewStopFollowingOperation(this, this.myUser.getUsername(), toStopUser); } else { if (logger.isInfoEnabled()) logger.info("Client with user:" + this.myUser + " generating new fake get friendsTimeLine operation."); res = this.opFactory.getNewGetFriendsTimeLineOperation(this, this.myUser.getUsername(), 0, 100); } } else { // Remaining Probability res = this.socialBenchmark.getNewTweetOperation(this.myUser, this); if (logger.isInfoEnabled()) logger.info("Client with user:" + this.myUser + " generating new tweet operation:" + res); } this.currentOp++; return new Pair<BenchOperation, Double>(res, this.thinkTime); } @Override public void handleFinishedComplexOperation(BenchOperation op) { boolean write = !op.isReadOnly(); statsCollector.registerRequest(Time.inMilliseconds(this.startTime), this.currentOp - 1, this.getPeerID(), Time.inMilliseconds(this.clock.getTime().subtract(startTime)), write, op.getName()); } @Override public boolean hasMoreComplexOperations() { return this.currentOp < this.nOperations; } }