package ldbc.snb.datagen.generator;
import ldbc.snb.datagen.dictionary.Dictionaries;
import ldbc.snb.datagen.objects.*;
import ldbc.snb.datagen.serializer.PersonActivityExporter;
import ldbc.snb.datagen.serializer.PersonActivitySerializer;
import ldbc.snb.datagen.serializer.UpdateEventSerializer;
import ldbc.snb.datagen.util.FactorTable;
import ldbc.snb.datagen.util.RandomGeneratorFarm;
import ldbc.snb.datagen.vocabulary.SN;
import org.apache.hadoop.mapreduce.Reducer.Context;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Random;
public class PersonActivityGenerator {
private ForumGenerator forumGenerator_ = null;
private RandomGeneratorFarm randomFarm_ = null;
private UniformPostGenerator uniformPostGenerator_ = null;
private FlashmobPostGenerator flashmobPostGenerator_ = null;
private PhotoGenerator photoGenerator_ = null;
private CommentGenerator commentGenerator_ = null;
private LikeGenerator likeGenerator_ = null;
private PersonActivitySerializer personActivitySerializer_ = null;
private UpdateEventSerializer updateSerializer_ = null;
private long forumId = 0;
private long messageId = 0;
private FactorTable factorTable_;
private PersonActivityExporter exporter_;
public PersonActivityGenerator( PersonActivitySerializer serializer, UpdateEventSerializer updateSerializer ) {
randomFarm_ = new RandomGeneratorFarm();
personActivitySerializer_ = serializer;
updateSerializer_ = updateSerializer;
forumGenerator_ = new ForumGenerator();
TextGenerator generator = new LdbcSnbTextGenerator(randomFarm_.get(RandomGeneratorFarm.Aspect.LARGE_TEXT), Dictionaries.tags);
likeGenerator_ = new LikeGenerator();
commentGenerator_ = new CommentGenerator(generator, likeGenerator_);
uniformPostGenerator_ = new UniformPostGenerator(generator, commentGenerator_, likeGenerator_);
flashmobPostGenerator_ = new FlashmobPostGenerator(generator, commentGenerator_, likeGenerator_);
photoGenerator_ = new PhotoGenerator(likeGenerator_);
factorTable_ = new FactorTable();
exporter_ = new PersonActivityExporter(personActivitySerializer_, updateSerializer_, factorTable_);
}
private void generateActivity( Person person, ArrayList<Person> block ) throws IOException {
try {
factorTable_.extractFactors(person);
generateWall(person, block);
generateGroups(person, block);
generateAlbums(person, block);
} catch (AssertionError e) {
System.out.println("Assertion error when generating activity!");
System.out.println(e.getMessage());
e.printStackTrace();
System.exit(1);
}
}
public void reset() {
personActivitySerializer_.reset();
}
private void generateWall( Person person, ArrayList<Person> block ) throws IOException {
// generate wall
Forum wall = forumGenerator_.createWall(randomFarm_, forumId++, person);
exporter_.export(wall);
for( ForumMembership fm : wall.memberships()) {
exporter_.export(fm);
}
// generate wall posts
ForumMembership personMembership = new ForumMembership(wall.id(),
wall.creationDate()+DatagenParams.deltaTime, new Person.PersonSummary(person)
);
ArrayList<ForumMembership> fakeMembers = new ArrayList<ForumMembership>();
fakeMembers.add(personMembership);
messageId = uniformPostGenerator_.createPosts(randomFarm_, wall, fakeMembers , numPostsPerGroup(randomFarm_, wall, DatagenParams.maxNumPostPerMonth, DatagenParams.maxNumFriends), messageId, exporter_);
messageId = flashmobPostGenerator_.createPosts(randomFarm_, wall, fakeMembers, numPostsPerGroup(randomFarm_, wall, DatagenParams.maxNumFlashmobPostPerMonth, DatagenParams.maxNumFriends), messageId, exporter_ );
}
private void generateGroups( Person person, ArrayList<Person> block ) throws IOException {
// generate user created groups
double moderatorProb = randomFarm_.get(RandomGeneratorFarm.Aspect.FORUM_MODERATOR).nextDouble();
if (moderatorProb <= DatagenParams.groupModeratorProb) {
int numGroup = randomFarm_.get(RandomGeneratorFarm.Aspect.NUM_FORUM).nextInt(DatagenParams.maxNumGroupCreatedPerUser)+1;
for (int j = 0; j < numGroup; j++) {
Forum group = forumGenerator_.createGroup(randomFarm_, forumId++, person, block);
exporter_.export(group);
for( ForumMembership fm : group.memberships()) {
exporter_.export(fm);
}
// generate uniform posts/comments
messageId = uniformPostGenerator_.createPosts(randomFarm_, group, group.memberships(), numPostsPerGroup(randomFarm_, group, DatagenParams.maxNumGroupPostPerMonth, DatagenParams.maxNumMemberGroup), messageId, exporter_);
messageId = flashmobPostGenerator_.createPosts(randomFarm_, group, group.memberships(), numPostsPerGroup(randomFarm_, group, DatagenParams.maxNumGroupFlashmobPostPerMonth, DatagenParams.maxNumMemberGroup),messageId, exporter_);
}
}
}
private void generateAlbums(Person person, ArrayList<Person> block ) throws IOException {
// generate albums
int numOfmonths = (int) Dictionaries.dates.numberOfMonths(person);
int numPhotoAlbums = randomFarm_.get(RandomGeneratorFarm.Aspect.NUM_PHOTO_ALBUM).nextInt(DatagenParams.maxNumPhotoAlbumsPerMonth+1);
if (numOfmonths != 0) {
numPhotoAlbums = numOfmonths * numPhotoAlbums;
}
for (int i = 0; i < numPhotoAlbums; i++) {
Forum album = forumGenerator_.createAlbum(randomFarm_, forumId++, person, i);
exporter_.export(album);
for( ForumMembership fm : album.memberships()) {
exporter_.export(fm);
}
ForumMembership personMembership = new ForumMembership(album.id(),
album.creationDate()+DatagenParams.deltaTime, new Person.PersonSummary(person)
);
ArrayList<ForumMembership> fakeMembers = new ArrayList<ForumMembership>();
fakeMembers.add(personMembership);
int numPhotos = randomFarm_.get(RandomGeneratorFarm.Aspect.NUM_PHOTO).nextInt(DatagenParams.maxNumPhotoPerAlbums+1);
messageId = photoGenerator_.createPhotos(randomFarm_, album, fakeMembers, numPhotos, messageId, exporter_);
}
}
private int numPostsPerGroup( RandomGeneratorFarm randomFarm, Forum forum, int maxPostsPerMonth, int maxMembersPerForum ) {
Random random = randomFarm.get(RandomGeneratorFarm.Aspect.NUM_POST);
int numOfmonths = (int) Dictionaries.dates.numberOfMonths(forum.creationDate());
int numberPost = 0;
if (numOfmonths == 0) {
numberPost = random.nextInt(maxPostsPerMonth+1);
} else {
numberPost = random.nextInt(maxPostsPerMonth * numOfmonths+1);
}
return (numberPost * forum.memberships().size()) / maxMembersPerForum;
}
public void generateActivityForBlock( int seed, ArrayList<Person> block, Context context ) throws IOException {
randomFarm_.resetRandomGenerators(seed);
forumId = 0;
messageId = 0;
SN.machineId = seed;
personActivitySerializer_.reset();
int counter = 0;
float personGenerationTime = 0.0f;
long initTime = System.currentTimeMillis();
for( Person p : block ) {
long start = System.currentTimeMillis();
generateActivity(p, block);
if( DatagenParams.updateStreams ) {
updateSerializer_.changePartition();
}
if( counter % 1000 == 0 ) {
context.setStatus("Generating activity of person "+counter+" of block"+seed);
context.progress();
}
float time = (System.currentTimeMillis() - start)/1000.0f;
personGenerationTime+=time;
//System.out.println("Time to generate activity for person "+counter+": "+time+". Throughput "+counter/((System.currentTimeMillis() - initTime)*0.001));
counter++;
}
System.out.println("Average person activity generation time "+personGenerationTime / (float)block.size());
}
public void writeActivityFactors( OutputStream writer) {
factorTable_.writeActivityFactors(writer);
}
public void writePersonFactors( OutputStream writer) {
factorTable_.writePersonFactors(writer);
}
}