// Boston, MA 02110-1301, USA.
using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using System.Threading;
using System.Threading.Tasks;
+using OpenTween.Setting;
namespace OpenTween.Models
{
public override MyCommon.TabUsageType TabType
=> MyCommon.TabUsageType.Home;
+ public int TweetsPerHour => this.tweetsPerHour;
+
+ // 流速計測用
+ private int tweetsPerHour = 0;
+ private ConcurrentDictionary<DateTimeUtc, int> tweetsTimestamps = new ConcurrentDictionary<DateTimeUtc, int>();
+
public HomeTabModel() : this(MyCommon.DEFAULTTAB.RECENT)
{
}
public HomeTabModel(string tabName) : base(tabName)
{
}
+
+ public override void AddPostQueue(PostClass post)
+ {
+ base.AddPostQueue(post);
+ this.UpdateTimelineSpeed(post.CreatedAt);
+ }
+
+ public override async Task RefreshAsync(Twitter tw, bool backward, bool startup, IProgress<string> progress)
+ {
+ bool read;
+ if (!SettingManager.Common.UnreadManage)
+ read = true;
+ else
+ read = startup && SettingManager.Common.Read;
+
+ progress.Report(string.Format(Properties.Resources.GetTimelineWorker_RunWorkerCompletedText5, backward ? -1 : 1));
+
+ await tw.GetHomeTimelineApi(read, this, backward, startup)
+ .ConfigureAwait(false);
+
+ // 新着時未読クリア
+ if (SettingManager.Common.ReadOldPosts)
+ TabInformations.GetInstance().SetReadHomeTab();
+
+ TabInformations.GetInstance().DistributePosts();
+
+ progress.Report(Properties.Resources.GetTimelineWorker_RunWorkerCompletedText1);
+ }
+
+ /// <summary>
+ /// タイムラインに追加された発言件数を反映し、タイムラインの流速を更新します
+ /// </summary>
+ private void UpdateTimelineSpeed(DateTimeUtc postCreatedAt)
+ {
+ var now = DateTimeUtc.Now;
+
+ // 1 時間以上前の時刻は追加しない
+ var oneHour = TimeSpan.FromHours(1);
+ if (now - postCreatedAt > oneHour)
+ return;
+
+ this.tweetsTimestamps.AddOrUpdate(postCreatedAt, 1, (k, v) => v + 1);
+
+ var removeKeys = new List<DateTimeUtc>();
+ var tweetsInWindow = 0;
+ foreach (var (timestamp, count) in this.tweetsTimestamps)
+ {
+ if (now - timestamp > oneHour)
+ removeKeys.Add(timestamp);
+ else
+ tweetsInWindow += count;
+ }
+ Interlocked.Exchange(ref this.tweetsPerHour, tweetsInWindow);
+
+ foreach (var key in removeKeys)
+ this.tweetsTimestamps.TryRemove(key, out var _);
+ }
}
}