/// <summary> /// Query popular topics today /// </summary> /// <param name="timeRange">Time range</param> /// <param name="hostAppHandle">Hosting app handle: Master app or client app</param> /// <param name="cursor">Read cursor</param> /// <param name="limit">Number of items to return</param> /// <returns>Topic feed entities</returns> public async Task <IList <ITopicFeedEntity> > QueryPopularTopics(TimeRange timeRange, string hostAppHandle, int cursor, int limit) { CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.PopularTopics); RankFeedTable table = this.tableStoreManager.GetTable(ContainerIdentifier.PopularTopics, TableIdentifier.PopularTopicsFeed) as RankFeedTable; string feedKey = this.GetPopularTopicsFeedKey(timeRange, hostAppHandle); // convert our current API cursor (an int) to a CTStore cursor (a string). Note that CTStore cursors // are offset by 1 from API cursors. This hack will be removed when we change our API to use string-based // cursors. string ctCursor; if (cursor == 0) { ctCursor = null; } else { ctCursor = (cursor - 1).ToString(); } var result = await store.QueryRankFeedReverseAsync(table, ContainerIdentifier.PopularTopics.ToString(), feedKey, ctCursor, limit); var convertedResults = result.Select(item => StoreSerializers.MinimalTopicRankFeedEntityDeserialize(item.ItemKey)); return(convertedResults.ToList <ITopicFeedEntity>()); }
/// <summary> /// Delete popular topic /// </summary> /// <param name="storageConsistencyMode">Storage consistency mode</param> /// <param name="timeRange">Time range</param> /// <param name="hostAppHandle">Hosting app handle: Master app or client app</param> /// <param name="appHandle">App handle</param> /// <param name="topicHandle">Topic handle</param> /// <param name="topicUserHandle">User handle</param> /// <returns>Delete popular topic task</returns> public async Task DeletePopularTopic( StorageConsistencyMode storageConsistencyMode, TimeRange timeRange, string hostAppHandle, string appHandle, string topicHandle, string topicUserHandle) { TopicRankFeedEntity topicRankFeedEntity = new TopicRankFeedEntity() { AppHandle = appHandle, TopicHandle = topicHandle, UserHandle = topicUserHandle }; var serializedEntity = StoreSerializers.MinimalTopicRankFeedEntitySerialize(topicRankFeedEntity); CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.PopularTopics); Transaction transaction = new Transaction(); RankFeedTable topicsTable = this.tableStoreManager.GetTable(ContainerIdentifier.PopularTopics, TableIdentifier.PopularTopicsFeed) as RankFeedTable; string feedKey = this.GetPopularTopicsFeedKey(timeRange, hostAppHandle); transaction.Add(Operation.DeleteIfExists(topicsTable, ContainerIdentifier.PopularTopics.ToString(), feedKey, serializedEntity)); if (timeRange != TimeRange.AllTime) { RankFeedTable expirationsTable = this.tableStoreManager.GetTable(ContainerIdentifier.PopularTopics, TableIdentifier.PopularTopicsExpirationsFeed) as RankFeedTable; transaction.Add(Operation.DeleteIfExists(expirationsTable, ContainerIdentifier.PopularTopics.ToString(), feedKey, serializedEntity)); } await store.ExecuteTransactionAsync(transaction, storageConsistencyMode.ToConsistencyMode()); }
/// <summary> /// Query popular topics maximum count /// </summary> /// <param name="timeRange">Time range</param> /// <returns>Maximum count of popular topics feeds</returns> public async Task <long> QueryPopularTopicsMaxCount(TimeRange timeRange) { CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.PopularTopics); RankFeedTable table = this.tableStoreManager.GetTable(ContainerIdentifier.PopularTopics, TableIdentifier.PopularTopicsFeed) as RankFeedTable; return(table.MaxFeedSizeInCache); }
/// <summary> /// Query popular topics count /// </summary> /// <param name="timeRange">Time range</param> /// <param name="hostAppHandle">Hosting app handle: Master app or client app</param> /// <returns>Popular topics feed length</returns> public async Task <long> QueryPopularTopicsCount(TimeRange timeRange, string hostAppHandle) { CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.PopularTopics); RankFeedTable table = this.tableStoreManager.GetTable(ContainerIdentifier.PopularTopics, TableIdentifier.PopularTopicsFeed) as RankFeedTable; string feedKey = this.GetPopularTopicsFeedKey(timeRange, hostAppHandle); return(await store.QueryRankFeedLengthAsync(table, ContainerIdentifier.PopularTopics.ToString(), feedKey)); }
/// <summary> /// Query popular users /// </summary> /// <param name="appHandle">App handle</param> /// <param name="cursor">Read cursor</param> /// <param name="limit">Number of items to return</param> /// <returns>User feed entities</returns> public async Task <IList <IUserFeedEntity> > QueryPopularUsers(string appHandle, int cursor, int limit) { CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.PopularUsers); RankFeedTable table = this.tableStoreManager.GetTable(ContainerIdentifier.PopularUsers, TableIdentifier.PopularUsersFeed) as RankFeedTable; var result = await store.QueryRankFeedAsync(table, ContainerIdentifier.PopularUsers.ToString(), appHandle, cursor.ToString(), limit); var convertedResults = result.Select(item => StoreSerializers.MinimalUserRankFeedEntityDeserialize(item.ItemKey)); return(convertedResults.ToList <IUserFeedEntity>()); }
/// <summary> /// Query popular topics expirations /// </summary> /// <param name="timeRange">Time range</param> /// <param name="hostAppHandle">Host app handle</param> /// <param name="expiration">Expiration time</param> /// <returns>Topic feed entities</returns> public async Task <IList <ITopicFeedEntity> > QueryPopularTopicsExpirations(TimeRange timeRange, string hostAppHandle, DateTime expiration) { CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.PopularTopics); RankFeedTable table = this.tableStoreManager.GetTable(ContainerIdentifier.PopularTopics, TableIdentifier.PopularTopicsExpirationsFeed) as RankFeedTable; string feedKey = this.GetPopularTopicsFeedKey(timeRange, hostAppHandle); var result = await store.QueryRankFeedByScoreAsync(table, ContainerIdentifier.PopularTopics.ToString(), feedKey, 0, expiration.ToFileTime()); var convertedResults = result.Select(item => StoreSerializers.MinimalTopicRankFeedEntityDeserialize(item.ItemKey)); return(convertedResults.ToList <ITopicFeedEntity>()); }
/// <summary> /// Query popular topics min score /// </summary> /// <param name="timeRange">Time range</param> /// <param name="hostAppHandle">Hosting app handle: Master app or client app</param> /// <returns>Score of the last entity in popular topics feed</returns> public async Task <long?> QueryPopularTopicsMinScore(TimeRange timeRange, string hostAppHandle) { CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.PopularTopics); RankFeedTable table = this.tableStoreManager.GetTable(ContainerIdentifier.PopularTopics, TableIdentifier.PopularTopicsFeed) as RankFeedTable; string feedKey = this.GetPopularTopicsFeedKey(timeRange, hostAppHandle); // querying the rank feed in reverse order with a null cursor and a limit of 1 extracts the min entry in the feed var result = await store.QueryRankFeedReverseAsync(table, ContainerIdentifier.PopularTopics.ToString(), feedKey, null, 1); if (result.Count > 0) { return((long)result.First().Score); } return(null); }
/// <summary> /// Delete popular user /// </summary> /// <param name="storageConsistencyMode">Storage consistency mode</param> /// <param name="userHandle">User handle</param> /// <param name="appHandle">App handle</param> /// <returns>Delete popular user topic task</returns> public async Task DeletePopularUser( StorageConsistencyMode storageConsistencyMode, string userHandle, string appHandle) { UserRankFeedEntity userRankFeedEntity = new UserRankFeedEntity() { AppHandle = appHandle, UserHandle = userHandle }; var serializedEntity = StoreSerializers.MinimalUserRankFeedEntitySerialize(userRankFeedEntity); CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.PopularUsers); RankFeedTable table = this.tableStoreManager.GetTable(ContainerIdentifier.PopularUsers, TableIdentifier.PopularUsersFeed) as RankFeedTable; Transaction transaction = new Transaction(); transaction.Add(Operation.DeleteIfExists(table, ContainerIdentifier.PopularUsers.ToString(), appHandle, serializedEntity)); transaction.Add(Operation.DeleteIfExists(table, ContainerIdentifier.PopularUsers.ToString(), MasterApp.AppHandle, serializedEntity)); await store.ExecuteTransactionAsync(transaction, storageConsistencyMode.ToConsistencyMode()); }
/// <summary> /// Insert popular user topic /// </summary> /// <param name="storageConsistencyMode">Storage consistency mode</param> /// <param name="userHandle">User handle</param> /// <param name="appHandle">App handle</param> /// <param name="topicHandle">Topic handle</param> /// <param name="score">Entity value</param> /// <returns>Insert popular user topic task</returns> public async Task InsertPopularUserTopic( StorageConsistencyMode storageConsistencyMode, string userHandle, string appHandle, string topicHandle, long score) { TopicRankFeedEntity topicRankFeedEntity = new TopicRankFeedEntity() { AppHandle = appHandle, TopicHandle = topicHandle, UserHandle = userHandle }; var serializedEntity = StoreSerializers.MinimalTopicRankFeedEntitySerialize(topicRankFeedEntity); CTStore store = await this.tableStoreManager.GetStore(ContainerIdentifier.PopularUserTopics); RankFeedTable table = this.tableStoreManager.GetTable(ContainerIdentifier.PopularUserTopics, TableIdentifier.PopularUserTopicsFeed) as RankFeedTable; Transaction transaction = new Transaction(); transaction.Add(Operation.InsertOrReplace(table, userHandle, appHandle, serializedEntity, score)); transaction.Add(Operation.InsertOrReplace(table, userHandle, MasterApp.AppHandle, serializedEntity, score)); await store.ExecuteTransactionAsync(transaction, storageConsistencyMode.ToConsistencyMode()); }