/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package ldbc.snb.datagen.generator; import ldbc.snb.datagen.dictionary.Dictionaries; import ldbc.snb.datagen.objects.FlashmobTag; import ldbc.snb.datagen.objects.Forum; import ldbc.snb.datagen.objects.ForumMembership; import ldbc.snb.datagen.util.Distribution; import java.util.*; import static ldbc.snb.datagen.generator.DatagenParams.maxNumTagPerFlashmobPost; /** * * @author aprat */ public class FlashmobPostGenerator extends PostGenerator{ private Distribution dateDistribution_; private FlashmobTag[] forumFlashmobTags = null; private long hoursToMillis_; private long flashmobSpan_; private long currentForum = -1; public FlashmobPostGenerator(TextGenerator generator, CommentGenerator commentGenerator, LikeGenerator likeGenerator) { super(generator, commentGenerator, likeGenerator); dateDistribution_ = new Distribution(DatagenParams.flashmobDistFile); hoursToMillis_ = 60*60*1000; flashmobSpan_ = 72 * hoursToMillis_; dateDistribution_.initialize(); } /** @brief Selects a random tag from a given index. * @param[in] tags The array of sorted tags to select from. * @param[in] index The first tag to consider. * @return The index of a random tag.*/ private int selectRandomTag( Random randomFlashmobTag, FlashmobTag[] tags, int index ) { int upperBound = tags.length - 1; int lowerBound = index; double prob = randomFlashmobTag.nextDouble() * (tags[upperBound].prob - tags[lowerBound].prob) + tags[lowerBound].prob; int midPoint = (upperBound + lowerBound) / 2; while (upperBound > (lowerBound+1)){ if (tags[midPoint].prob > prob ){ upperBound = midPoint; } else{ lowerBound = midPoint; } midPoint = (upperBound + lowerBound) / 2; } return midPoint; } /** @brief Selects the earliest flashmob tag index from a given date. * @return The index to the earliest flashmob tag.*/ private int searchEarliest( FlashmobTag[] tags, ForumMembership membership ) { long fromDate = membership.creationDate() + flashmobSpan_/2 + DatagenParams.deltaTime; int lowerBound = 0; int upperBound = tags.length - 1; int midPoint = (upperBound + lowerBound) / 2; while (upperBound > (lowerBound+1)){ if (tags[midPoint].date > fromDate ){ upperBound = midPoint; } else{ lowerBound = midPoint; } midPoint = (upperBound + lowerBound) / 2; } if( tags[midPoint].date < fromDate ) return -1; return midPoint; } private void populateForumFlashmobTags( Random randomNumPost, Forum forum ) { ArrayList<Integer> forumTags = forum.tags(); TreeSet<Integer> tags = new TreeSet<Integer>(); for( Integer tag : tags ) { tags.add(tag); } ArrayList<FlashmobTag> temp = Dictionaries.flashmobs.generateFlashmobTags( randomNumPost, tags, forum.creationDate() ); forumFlashmobTags = new FlashmobTag[temp.size()]; Iterator<FlashmobTag> it = temp.iterator(); int index = 0; int sumLevels = 0; while(it.hasNext()) { FlashmobTag flashmobTag = new FlashmobTag(); it.next().copyTo(flashmobTag); forumFlashmobTags[index] = flashmobTag; sumLevels+=flashmobTag.level; ++index; } Arrays.sort(forumFlashmobTags); int size = forumFlashmobTags.length; double currentProb = 0.0; for( int i = 0; i < size; ++i ) { forumFlashmobTags[i].prob = currentProb; currentProb += (double)(forumFlashmobTags[i].level) / (double)(sumLevels); } } protected PostGenerator.PostInfo generatePostInfo( Random randomTag, Random randomDate, final Forum forum, final ForumMembership membership ) { if( currentForum != forum.id() ) { populateForumFlashmobTags(randomTag,forum); currentForum = forum.id(); } if( forumFlashmobTags.length < 1 ) return null; PostInfo postInfo = new PostInfo(); int index = searchEarliest(forumFlashmobTags,membership); if( index < 0 ) return null; index = selectRandomTag( randomTag, forumFlashmobTags,index); FlashmobTag flashmobTag = forumFlashmobTags[index]; postInfo.tags.add(flashmobTag.tag); /*Set<Integer> extraTags = Dictionaries.tagMatrix.getSetofTagsCached(randomTag,randomTag,flashmobTag.tag, maxNumTagPerFlashmobPost - 1); Iterator<Integer> it = extraTags.iterator(); while (it.hasNext()) { Integer value = it.next(); if(randomTag.nextDouble() < 0.05) { postInfo.tags.add(value); } } */ for(int i = 0; i < maxNumTagPerFlashmobPost - 1 ; ++i) { if(randomTag.nextDouble() < 0.05) { int tag = Dictionaries.tagMatrix.getRandomRelated(randomTag,flashmobTag.tag); postInfo.tags.add(tag); } } double prob = dateDistribution_.nextDouble(randomDate); postInfo.date = flashmobTag.date - flashmobSpan_/2 + (long)(prob * flashmobSpan_); //if( postInfo.date > Dictionaries.dates.getEndDateTime() ) return null; return postInfo; } }