Example #1
0
        public void DestroyChannelBucket(ChannelBucket type, ulong channelId)
        {
            //Assume this object is locked
            RequestQueueBucket bucket;

            _channelBuckets[(int)type].TryRemove(channelId, out bucket);
        }
Example #2
0
        /// <summary>
        /// Picks a random asset from the content exchanger-generated Playlist
        /// </summary>
        /// <param name="playlist">The content exchanger-generated Playlist</param>
        /// <param name="assetScheduler">Asset Scheduler object that determines which assets are temporally capable of being played</param>
        /// <returns>The information on the content playlist asset, null if no available asset found</returns>
        private ChannelAssetAssociation PickRandomContentPlaylistAsset()
        {
            // this counts the number of buckets we have already tried and have not found any content in.
            int noConsumedChannelBuckets = _consumedChannelBuckets.Count;

            _logger.WriteMessage("Attempted Channel Buckets: " + noConsumedChannelBuckets);

            // if user has not subscribed to any channels or if all channel buckets have been searched, return null
            // clear consumed buckets to search again on the next run
            if (_noChannelBuckets == 0 || _noChannelBuckets == noConsumedChannelBuckets)
            {
                _consumedChannelBuckets.Clear();
                _consumedContentPlaylistAssets.Clear();

                if (_noChannelBuckets > 0)
                {
                    _logger.WriteMessage("All channel buckets searched. No content asset can be played at this time.");
                }
                else
                {
                    _logger.WriteMessage("No channel buckets in playlist. No content asset can be played at this time.");
                }

                return(null);
            }

            ChannelBucket cb = GetRandomChannelBucket(_playlist);

            _logger.WriteMessage("channel bucket selected successfully");

            ChannelAssetAssociation caa = GetRandomContentPlaylistAsset(cb);

            if (caa == null)
            {
                _consumedChannelBuckets.Add(cb);

                _logger.WriteMessage("no content in this channel was selected. Channel bucket will not be attempted again in this run. Attempting another channel bucket.");

                caa = PickRandomContentPlaylistAsset();
            }
            else
            {
                _logger.WriteMessage("content asset selected: " + caa.PlaylistAsset.AssetID + " in channel: " + caa.ChannelID);
            }

            // at this point the algorithm has succeeded or has processed all buckets and assets and found no content available
            // clear consumed
            _consumedChannelBuckets.Clear();
            _consumedContentPlaylistAssets.Clear();

            // next pick will include content web assets if due to network/website unavailability those were excluded
            _bIncludeContentWebAssets = true;

            return(caa); // if this is null, there is no content asset available for playing
        }
Example #3
0
        public static void NormalizeChannelBucketPlayingProbabilities(HashSet <ChannelBucket> channelBuckets, Logger logger)
        {
            float sumPlayingProbabilities          = 0F;
            float normalisedPlayingProbability     = -1F;
            float previousLowerThresholdNormalised = 0F;

            foreach (ChannelBucket cb in channelBuckets)
            {
                sumPlayingProbabilities += cb.PlayingProbabilityUnnormalized;
            }

            // normalize playing probabilities if there is at least a playing probability greater than 0.
            if (sumPlayingProbabilities <= 0)
            {
                return;
            }

            int noChannelBuckets = channelBuckets.Count;

            for (int i = 0; i < noChannelBuckets; i++)
            {
                ChannelBucket cb = channelBuckets.ElementAt(i);

                normalisedPlayingProbability = cb.PlayingProbabilityUnnormalized / sumPlayingProbabilities;

                cb.PlayingProbabilityNormalised = normalisedPlayingProbability;

                // calculate lower and upper threshold for random play
                cb.LowerThresholdNormalised = previousLowerThresholdNormalised;

                // make last content asset's higher normalized threshold equal to 1, else add the newly calculated normalized weighting.
                if (i < noChannelBuckets - 1)
                {
                    cb.HigherThresholdNormalised = previousLowerThresholdNormalised + normalisedPlayingProbability;
                }
                else
                {
                    cb.HigherThresholdNormalised = 1;
                }

                // increment lower threshold for next loop run
                previousLowerThresholdNormalised += normalisedPlayingProbability;
            }
        }
Example #4
0
        // filter non consumed content assets
        private IEnumerable <ContentPlaylistAsset> GetPlayableContentPlaylistAssetsExcludingConsumed(ChannelBucket cb)
        {
            _logger.WriteMessage("shortlisting non attempted content assets that can be displayed and selecting one randomly.");

            // filter by whether content assets are consumed
            var channelBucketContentNonConsumedPlayable = from ContentPlaylistAsset contentPlaylistAsset in cb.ContentAssets
                                                          where !_consumedContentPlaylistAssets.Contains(contentPlaylistAsset)
                                                          select contentPlaylistAsset;

            _logger.WriteMessage("successfully selected the non attempted content.");

            // further filter by date bounds
            var channelBucketContentDateNonConsumedPlayable = from ContentPlaylistAsset contentPlaylistAsset in channelBucketContentNonConsumedPlayable
                                                              where contentPlaylistAsset.StartDateTime <= DateTime.Now &&
                                                              contentPlaylistAsset.EndDateTime >= DateTime.Now
                                                              select contentPlaylistAsset;

            _logger.WriteMessage("successfully selected the non attempted content whose start and end date/time surround today/now.");

            // further filter assets that passed date bound filtering by content assets with no scheduling information
            var channelBucketContentDateNonConsumedNoScheduleInfoPlayable = from ContentPlaylistAsset contentPlaylistAsset in channelBucketContentDateNonConsumedPlayable
                                                                            where contentPlaylistAsset.ScheduleInfo.Length == 0
                                                                            select contentPlaylistAsset;

            _logger.WriteMessage("successfully selected the non attempted content with no scheduling info.");

            // further filter assets that passed date bound filtering by content assets with scheduling information that permits them to be played at this time
            var channelBucketContentDateNonConsumedWithScheduleInfoPlayable = from ContentPlaylistAsset contentPlaylistAsset in channelBucketContentDateNonConsumedPlayable
                                                                              where _assetScheduler.IsAssetPlayable(contentPlaylistAsset.ScheduleInfo)
                                                                              select contentPlaylistAsset;

            _logger.WriteMessage("successfully selected the non attempted content with permitted scheduling info.");

            // union of assets passed scheduling information and assets with no scheduling information
            var playableContentAssets = channelBucketContentDateNonConsumedNoScheduleInfoPlayable.Union(channelBucketContentDateNonConsumedWithScheduleInfoPlayable);

            _logger.WriteMessage("successfully combined playable content with permitted scheduling info and without scheduling info.");

            // of those assets found, which ones are available and can be played due to memory restrictions if any
            var playableContentAssetsExisting = from ContentPlaylistAsset contentPlaylistAsset in playableContentAssets
                                                where ((contentPlaylistAsset.PlayerType == PlayerType.WebSite && AssetWebsiteExists(contentPlaylistAsset.AssetWebSite)) ||
                                                       contentPlaylistAsset.PlayerType != PlayerType.WebSite && AssetFileExists(contentPlaylistAsset.GetAssetFilenameGUIDSuffix(), contentPlaylistAsset.AssetFilename) &&
                                                       (!_bInsufficientMemoryForLargeFiles || IsNonLargeFile(contentPlaylistAsset)))
                                                select contentPlaylistAsset;

            _logger.WriteMessage("successfully selected content that is available locally or online.");

            return(playableContentAssetsExisting);
        }
Example #5
0
        // picks a random content asset from channel bucket
        private ChannelAssetAssociation GetRandomContentPlaylistAsset(ChannelBucket cb)
        {
            // Randomly pick asset from full bucket list
            // check whether selected asset can be played according to temporal scheduling
            // if not pick again. This will be repeated 20 times.
            for (int i = 0; i < 20; i++)
            {
                ContentPlaylistAsset contentPlaylistAsset = GetRandomElement(cb.ContentAssets);

                if (contentPlaylistAsset == null)
                {
                    _logger.WriteMessage("no asset found in this channel bucket.");
                    return(null);
                }

                _logger.WriteMessage("content asset: " + contentPlaylistAsset.AssetID +
                                     " selected randomly. Determining if it can be played at this time.");

                if (_consumedContentPlaylistAssets.Contains(contentPlaylistAsset))
                {
                    continue;
                }

                _logger.WriteMessage("content asset has not been attempted on this run.");

                if (!((contentPlaylistAsset.StartDateTime <= DateTime.Now &&
                       contentPlaylistAsset.EndDateTime >= DateTime.Now
                       &&
                       (contentPlaylistAsset.PlayerType != PlayerType.WebSite ||
                        _bIncludeContentWebAssets && contentPlaylistAsset.PlayerType == PlayerType.WebSite))) ||
                    (!_assetScheduler.IsAssetPlayable(contentPlaylistAsset.ScheduleInfo)))
                {
                    _consumedContentPlaylistAssets.Add(contentPlaylistAsset);
                    continue;
                }



                _logger.WriteMessage("content asset has no schedule info. Checking if it is available.");

                if (contentPlaylistAsset.PlayerType == PlayerType.WebSite)
                {
                    _logger.WriteMessage("content asset is a website. Checking if it is available online.");

                    if (AssetWebsiteExists(contentPlaylistAsset.AssetWebSite))
                    {
                        _logger.WriteMessage("content asset " + contentPlaylistAsset.AssetWebSite +
                                             " is available online and will be selected.");
                        return(new ChannelAssetAssociation(cb.ChannelID, contentPlaylistAsset));
                    }

                    _logger.WriteMessage("content asset " + contentPlaylistAsset.AssetWebSite +
                                         " is not available online. Disabling selection of web content for this run.");
                    _bIncludeContentWebAssets = false;
                }
                else
                {
                    _logger.WriteMessage("content asset is a non-website. Checking if it is available on disk.");

                    if (AssetFileExists(contentPlaylistAsset.GetAssetFilenameGUIDSuffix(),
                                        contentPlaylistAsset.AssetFilename))
                    {
                        _logger.WriteMessage("content asset " + contentPlaylistAsset.AssetFilename +
                                             " exists on disk.");

                        if (!_bInsufficientMemoryForLargeFiles || IsNonLargeFile(contentPlaylistAsset))
                        {
                            _logger.WriteTimestampedMessage("Content asset " + contentPlaylistAsset.AssetFilename +
                                                            " can be played.");
                            return(new ChannelAssetAssociation(cb.ChannelID, contentPlaylistAsset));
                        }

                        _logger.WriteTimestampedMessage(
                            "There are physical memory restrictions and content asset " +
                            contentPlaylistAsset.AssetFilename + " cannot be played");
                    }
                    else
                    {
                        _logger.WriteMessage("content asset " + contentPlaylistAsset.AssetFilename +
                                             " does not exist on disk.");
                    }
                }


                _consumedContentPlaylistAssets.Add(contentPlaylistAsset);
            }

            // if nothing found go through Channel Bucket's entire list (excluding the consumed ones),
            // checking what CAN be displayed and create a shortlist
            // then randomly pick one from the shortlist.
            ContentPlaylistAsset cpa = GetRandomElement(GetPlayableContentPlaylistAssetsExcludingConsumed(cb));

            if (cpa == null)
            {
                return(null);
            }

            return(new ChannelAssetAssociation(cb.ChannelID, cpa));
        }
Example #6
0
 public static Bucket GetBucketInfo(ChannelBucket bucket) => _channelLimits[bucket];
Example #7
0
 private RequestQueueBucket GetChannelBucket(ChannelBucket type, ulong channelId)
 {
     return(_channelBuckets[(int)type].GetOrAdd(channelId, _ => CreateBucket(_channelLimits[type])));
 }